home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Just Call Me Internet
/
Just Call Me Internet.iso
/
prog
/
atari
/
m2
/
cat3src
/
cat
/
wdwmanag.i
< prev
next >
Wrap
Text File
|
1997-10-26
|
124KB
|
4,057 lines
IMPLEMENTATION MODULE WdwManager;
(*==============================================================*
* Modul: WdwManager - Window-Verwaltung fr *
* alle Module *
* Autor: Dirk Steins *
* erstellt am: 3.4.1992 *
* letzte nderung am: 29.6.1993 *
* Version: 0.7 *
* Interne Version: V#0004 *
*==============================================================*
*----------------------------------------------------------------------------
* Datum Vers. Autor nderung (Arbeitsbericht)
*----------------------------------------------------------------------------
*
* 12.4.92 0.35 DS Tastaturclick jetzt ausgeschaltet mit nur
* noch zwei SupExecs. Das ganze ist trotzdem
* unsauber, da auf fremden Speicher zugegriffen wird.
* In zuknftigen Versionen mu man dann mal sehen, was
* MultiTOS mit Memory Protection dazu sagen wird.
* 4.12.92 0.4 DS Anpassung an WMBOTTOMED
* 9.12.92 0.45 DS Bei mehr als zwei Fenstern funktionierte WFBOTTOMED
* nicht richtig. Behoben
* 23.5.93 0.5 DS Anpassung an Atari Nachrichtennummer fr WFBOTTOMED
* 15.6.93 0.6 DS Anpassung an erweiterte Scrollfunktionen von WINX
* 29.6.93 0.7 DS Anpassung an Iconify und andere Sachen in AES 4.1.
* Tastaturrepeat ber SupExecs ist schon lnger wieder
* drauen
*
*
*
*----------------------------------------------------------------------------
*)
(*$Z+*)
FROM SYSTEM IMPORT LOC, ADDRESS, ADR, LONGWORD, CALLSYS, CADR;
FROM GrafBase IMPORT Rectangle, LongRect;
FROM Storage IMPORT ALLOCATE, DEALLOCATE;
IMPORT BinOps, Strings;
IMPORT MagicSys, MagicAES, MagicVDI, MagicXBIOS, MagicDOS, MagicCookie;
IMPORT mtAppl, mtUtils;
IMPORT Mintbind;
FROM MagicVDI IMPORT VDIIntIn, VDIPtsIn, VDIControl;
FROM Void IMPORT v;
IMPORT RectFuncs;
IMPORT StrConv;
CONST
minWindWidth = 80;
minWindHeight = 80;
(* Typdefinition *)
TYPE
ptrWdwSlot = POINTER TO wdwSlot;
wdwSlot = RECORD
wdw : INTEGER; (* Window-Handle *)
vdi : INTEGER; (* VDI-Workstation fr Fenster *)
used,
isFull,
isTop,
isHidden,
isIcon : BOOLEAN;
wdwLast,
wdwCurr,
wdwIcon,
wdwWork,
wdwFull : Rectangle;
document : LongRect;
xFactor,
yFactor : LONGINT; (* Multiplikatoren fr Document-Struktur *)
pageW,
pageH : LONGINT; (* Breite und Hhe einer Seite in Einheiten *)
minScrollW,
minScrollH: LONGINT; (* Um diesen Betrag wird beim Zeilenweise scrollen gescrollt *)
pixOff : INTEGER; (* Offset am linken Fensterrand in Pixeln *)
snap : BOOLEAN; (* Snap on Font-Size *)
comps : BITSET;
wdwInfo : ARRAY [0..139] OF CHAR;
wdwTitle : ARRAY [0..139] OF CHAR;
VslSize,
VslPos,
HslSize,
HslPos : INTEGER; (* Die Positionen und Gren der Slider *)
onlyTop : BOOLEAN; (* Nur dieses Fenster darf Topwindow sein *)
lastOnlyTop: INTEGER; (* Fensternummer des letzten Windows, welches nur Top sein durfte *)
wdwMenu : ADDRESS; (* Adresse eines Menus im Fenster *)
wdwDial : ADDRESS; (* Adresse eines Dials im Fenster *)
(* Prozeduren *)
hdlButton : handleButtonProc;
hdlKey : handleKeyProc;
hdlTimer : handleTimerProc;
hdlRect : handleRectProc;
hdlSnap : snapProc;
hdlClose : closeProc;
hdlDraw : drawProc;
hdlTop : topProc; (* Wird aufgerufen, wenn das Fenster getoppt
* werden soll. Kann auch False zurckgeben
*)
hdlUntop : untopProc;
hdlUpdate : updateProc; (* Wird aufgerufen vor
* geplanten Bildschirmausgaben *)
setNewWdw : setWorkProc;
wdwGetScroll : getRectProc;
(* wird aufgerufen, wenn der Arbeits-
* ausschnitt des Fensters sich
* verndert hat.
*)
hdlHide : hideProc;
(* wird aufgerufen, wenn das Fenster iconifiziert
* oder versteckt wird bzw. beim Wiederherstellen
*)
(* Drag & Drop Support *)
ddClientInstalled : BOOLEAN;
ddGetExts : getExtsProc;
ddAcceptData: acceptDataProc;
ddWriteData : writeDataProc;
ddServerInstalled: BOOLEAN;
ddReadData : readDataProc;
ddGetHeader : getHeaderProc;
special : ADDRESS; (* Variabler Parameter *)
next,
prev : ptrWdwSlot;
END;
(* globale Variablen in diesem Modul *)
VAR windows : ptrWdwSlot;
control7: POINTER TO ADDRESS; (* it's tricky... *)
control9: POINTER TO ADDRESS;
multiTOS: BOOLEAN;
magIx: BOOLEAN;
magIxVer: CARDINAL;
onlyOneTop: INTEGER;
iconHdl: ADDRESS;
allIconified: BOOLEAN;
iconifySupportEnabled: BOOLEAN;
isInRectList: BOOLEAN; (* Gerade in WF_FIRST, WF_NEXT *)
globalMenu : ADDRESS;
menuLength : INTEGER;
menuDisabled: BOOLEAN;
MagicPCKeyTrans: BOOLEAN;
disableCounter: INTEGER;
handleGlobalKey: handleGlobalKeyProc;
handleGlobalMess: handleMessProc;
(*====================================================*
* *
* Forward-Funktionen *
* *
*====================================================*)
PROCEDURE SendClosed (wdw : INTEGER; apId : INTEGER); FORWARD;
PROCEDURE SendFulled (wdw : INTEGER; apId : INTEGER); FORWARD;
PROCEDURE SendTop (wdw : INTEGER; apId : INTEGER); FORWARD;
(*====================================================*
* *
* Low-Level-Funktionen *
* *
*====================================================*)
(* Rechteck- und Clipfunctionen *)
PROCEDURE SetClip (hdl : INTEGER; clip : ARRAY OF LOC; relative : BOOLEAN);
VAR cl : POINTER TO Rectangle;
BEGIN
cl := ADR (clip);
IF relative
THEN
WITH cl^ DO
INC (w, x); DEC (w);
INC (h, y); DEC (h);
END;
END;
IF hdl > 0 THEN MagicVDI.SetClipping (hdl, cl^, TRUE); END;
END SetClip;
PROCEDURE ClipWork (wdwPtr : ptrWdwSlot);
VAR clip : Rectangle;
BEGIN
clip := RectFuncs.ClipRect (deskSize, wdwPtr^.wdwWork);
SetClip (wdwPtr^.vdi, clip, TRUE);
END ClipWork;
PROCEDURE RectList (wdw: INTEGER; flag: INTEGER;
VAR work: Rectangle): BOOLEAN;
(* Gibt TRUE und ein Rechteck zurck, solange noch
* ein Rechteck in der Rechteckliste ist
*)
VAR b: BOOLEAN;
BEGIN
b:= FALSE;
IF wdw > 0 THEN
MagicAES.WindGet (wdw, flag + 11, work);
b:= NOT ((work.w = 0) OR (work.h = 0));
END;
isInRectList := b;
RETURN b;
END RectList;
PROCEDURE RectListActive (): BOOLEAN;
BEGIN
RETURN isInRectList;
END RectListActive;
(* Default-Prozeduren *)
PROCEDURE defDraw (wdw, vdi: INTEGER; special: ADDRESS; clip: Rectangle);
BEGIN
IF vdi > 0
THEN
mtUtils.AbsRect (clip);
v.int := MagicVDI.SetFillcolor (vdi, 0); (* wei *)
v.int := MagicVDI.SetFillinterior (vdi, 1); (* solide *)
MagicVDI.FillRectangle(vdi, clip);
END;
END defDraw;
PROCEDURE defButton (wdw, vdi: INTEGER; special: ADDRESS; mx, my : INTEGER;
kstate, buttons : BITSET; clicks: INTEGER): BOOLEAN;
BEGIN
RETURN FALSE
END defButton;
PROCEDURE defKey (wdw, vdi: INTEGER; special: ADDRESS; taste: INTEGER; key, scan: CHAR; kstate: BITSET): BOOLEAN;
BEGIN
RETURN FALSE
END defKey;
PROCEDURE defTimer (wdw, vdi: INTEGER; special: ADDRESS): BOOLEAN;
BEGIN
RETURN FALSE
END defTimer;
PROCEDURE defRect (wdw, vdi: INTEGER; special: ADDRESS; which: INTEGER): BOOLEAN;
BEGIN
RETURN FALSE
END defRect;
PROCEDURE defSnap (wdw, vdi: INTEGER; special: ADDRESS; VAR r: Rectangle);
END defSnap;
PROCEDURE defClose (wdw, vdi: INTEGER; special: ADDRESS; force: BOOLEAN): BOOLEAN;
BEGIN
RETURN TRUE
END defClose;
PROCEDURE defTop (wdw, vdi: INTEGER; special: ADDRESS): BOOLEAN;
BEGIN
RETURN TRUE
END defTop;
PROCEDURE defUntop (wdw, vdi: INTEGER; special: ADDRESS);
END defUntop;
PROCEDURE defUpdate (wdw, vdi: INTEGER; special: ADDRESS; begin: BOOLEAN);
BEGIN
IF begin
THEN
MagicAES.WindUpdate (MagicAES.BEGUPDATE);
mtAppl.MouseOff();
ELSE
mtAppl.MouseOn();
MagicAES.WindUpdate (MagicAES.ENDUPDATE);
END;
END defUpdate;
PROCEDURE defSetwork (wdw, vdi: INTEGER; special: ADDRESS; doc: LongRect; slided: BOOLEAN);
END defSetwork;
PROCEDURE defGetrect (wdw, vdi: INTEGER; special: ADDRESS; VAR work: Rectangle);
END defGetrect;
PROCEDURE defHide (wdw, vdi: INTEGER; special: ADDRESS; hide: BOOLEAN);
END defHide;
(* Window neu zeichnen *)
PROCEDURE AdaptIconPos (work : Rectangle);
VAR ob : POINTER TO MagicAES.OBJECT;
rp : POINTER TO Rectangle;
BEGIN
IF iconHdl # NIL
THEN
ob := iconHdl;
rp := ADR(ob^.obX);
rp^ := work;
(*
WITH ob^ DO
obX := work.x;
obY := work.y;
obWidth := work.w;
obHeight := work.h;
END;
*)
END;
END AdaptIconPos;
PROCEDURE updateWdw (wdwPtr : ptrWdwSlot; frame : Rectangle);
(* In dieser Prozedur wird die Rechteckliste abgeklappert und
* fr alle Rechtecke, die vorhanden sind,
* die Zeichenprozedur fr das Fenster aufgerufen.
* Clipping wird schon gesetzt.
*)
VAR work : Rectangle;
c : Rectangle;
BEGIN
WITH wdwPtr^ DO
IF isIcon
THEN
MagicAES.WindGet (wdw, MagicAES.WFWORKXYWH, wdwWork);
AdaptIconPos (wdwWork);
IF RectList (wdw, 0, work)
THEN
MagicAES.WindUpdate (MagicAES.BEGUPDATE);
MagicAES.GrafMouse (MagicAES.MOFF, NIL);
REPEAT
(* kleinsten Redrawbereich bestimmen *)
c := RectFuncs.ClipRect (work, deskSize);
c := RectFuncs.ClipRect (frame, c);
IF (c.w > 0) & (c.h > 0) THEN
SetClip (vdi, c, TRUE);
IF iconHdl # NIL
THEN
MagicAES.ObjcDraw (iconHdl, 0, 8, c);
ELSIF vdi > 0
THEN
(* Nur lschen mit aktuellen Attributen und Farbe! *)
(* v.int := MagicVDI.SetFillcolor (vdi, 0); *)
c.w := c.x + c.w - 1;
c.h := c.y + c.h - 1;
MagicVDI.FillRectangle(vdi, c);
END;
END;
UNTIL ~RectList (wdw, 1, work);
MagicAES.GrafMouse (MagicAES.MON, NIL);
MagicAES.WindUpdate (MagicAES.ENDUPDATE);
END;
ELSE
hdlUpdate (wdw, vdi, special, TRUE);
IF RectList (wdw, 0, work)
THEN
REPEAT
(* kleinsten Redrawbereich bestimmen *)
c := RectFuncs.ClipRect (work, deskSize);
c := RectFuncs.ClipRect (frame, c);
IF (c.w > 0) & (c.h > 0) THEN
SetClip (vdi, c, TRUE);
hdlDraw (wdw, vdi, special, c);
END;
UNTIL ~RectList (wdw, 1, work);
END;
hdlUpdate (wdw, vdi, special, FALSE);
END;
END;
END updateWdw;
(* Scroll-Funktionen *)
PROCEDURE rawScroll (wdwPtr: ptrWdwSlot; dir: INTEGER;
VAR area : Rectangle;
height: INTEGER; amount: INTEGER);
(* Fr eine schnellere Ausfhrung der Blit-Operationen
* werden hier die VDI-Arrays direkt gefllt und direkt
* der entsprechende Call ausgefhrt, ohne ber die
* Library zu gehen.
*)
VAR screen : MagicVDI.MFDB;
BEGIN
(* build screen MFDB *)
screen.fdWdwidth:= (mtAppl.MaxWidth + 15) DIV 16;
screen.fdW:= screen.fdWdwidth * 16;
screen.fdH:= mtAppl.MaxHeight;
screen.fdStand:= 0;
screen.fdNplanes:= mtAppl.Bitplanes;
screen.fdAddr:= NIL;
(* erst kopieren *)
VDIIntIn[0]:= 3; (* E = Q *)
control7^:= ADR (screen);
control9^:= ADR (screen);
IF dir = UP
THEN
(* scrollUp *)
WITH area DO
VDIPtsIn[0]:= x;
VDIPtsIn[1]:= y;
VDIPtsIn[2]:= x + w - 1;
VDIPtsIn[3]:= y + height - 1;
VDIPtsIn[4]:= x;
VDIPtsIn[5]:= y + amount;
VDIPtsIn[6]:= x + w - 1;
VDIPtsIn[7]:= y + height + amount - 1;
END;
WITH wdwPtr^ DO
MagicVDI.VDICall (109, 4, 1, 0, vdi);
(* jetzt RectFuncs.ClipRect berechnen und neu zeichnen *)
IF area.x - 2 <= wdwPtr^.wdwWork.x
THEN
INC (area.x, pixOff);
DEC (area.w, pixOff);
END;
SetClip (vdi, Rectangle{area.x, area.y, area.w, amount}, TRUE);
hdlDraw (wdw, vdi, special, Rectangle{area.x, area.y, area.w, amount});
END;
ELSE
(* scroll down *)
WITH area DO
VDIPtsIn[0]:= x;
VDIPtsIn[1]:= y + amount ;
VDIPtsIn[2]:= x + w - 1;
VDIPtsIn[3]:= y + height + amount - 1;
VDIPtsIn[4]:= x;
VDIPtsIn[5]:= y ;
VDIPtsIn[6]:= x + w - 1;
VDIPtsIn[7]:= y + height - 1;
END;
WITH wdwPtr^ DO
MagicVDI.VDICall (109, 4, 1, 0, vdi);
IF area.x - 2 <= wdwPtr^.wdwWork.x
THEN
INC (area.x, pixOff);
DEC (area.w, pixOff);
END;
(* jetzt RectFuncs.ClipRect berechnen und neu zeichnen *)
SetClip (vdi, Rectangle{area.x, area.y+height, area.w, amount}, TRUE);
hdlDraw (wdw, vdi, special, Rectangle{area.x, area.y+height, area.w, amount});
END;
END;
END rawScroll;
PROCEDURE FindWindow (wdw : INTEGER) : ptrWdwSlot; FORWARD;
PROCEDURE ScrollInWdw (wdw: INTEGER; VAR source: Rectangle;
dir: INTEGER; amount: INTEGER);
VAR wdwPtr: ptrWdwSlot;
copyLines : INTEGER;
work, c : Rectangle;
BEGIN
wdwPtr := FindWindow (wdw);
IF wdwPtr # NIL
THEN
WITH wdwPtr^ DO
source := RectFuncs.ClipRect (wdwWork, source);
(* Rechteckliste abfragen *)
IF RectList (wdw, 0, work)
THEN
hdlUpdate (wdw, vdi, special, TRUE);
REPEAT
ClipWork (wdwPtr);
(* kleinsten Redrawbereich bestimmen *)
c := RectFuncs.ClipRect (work, deskSize);
c := RectFuncs.ClipRect (c, source);
copyLines := c.h-amount;
IF (c.w > 0) & (copyLines > 0) THEN
rawScroll (wdwPtr, dir, c, copyLines, amount);
ELSIF c.w > 0
THEN
SetClip (vdi, c, TRUE);
hdlDraw (wdw, vdi, special, c);
END;
ClipWork (wdwPtr);
UNTIL ~RectList (wdw, 1, work);
hdlUpdate (wdw, vdi, special, FALSE);
END;
(*
rawScroll (wdwPtr, dir, source, source.h, amount);
*)
END;
END;
END ScrollInWdw;
PROCEDURE scrollWdw (wdwPtr : ptrWdwSlot; dir : INTEGER; lines : LONGINT);
(* lines ist der Betrag in Pixelzeilen, um den gescrollt werden soll.
*)
VAR
pixLines : INTEGER;
copyLines : INTEGER;
work, c : Rectangle;
VAR x, y, w, h : INTEGER;
BEGIN
WITH wdwPtr^ DO
IF isIcon OR isHidden THEN RETURN END;
(* calc scroll Area *)
(* calc pixel lines *)
IF (lines <= LONG(wdwWork.h))
THEN
pixLines := SHORT(lines);
copyLines := (wdwWork.h - SHORT(lines));
END;
IF (lines < LONG(wdwWork.h))
THEN
(* Rechteckliste abfragen *)
IF RectList (wdw, 0, work)
THEN
hdlUpdate (wdw, vdi, special, TRUE);
REPEAT
ClipWork (wdwPtr);
(* kleinsten Redrawbereich bestimmen *)
c := RectFuncs.ClipRect (work, deskSize);
c := RectFuncs.ClipRect (c, wdwWork);
copyLines := c.h-SHORT(lines);
IF (c.w > 0) & (copyLines > 0) THEN
rawScroll (wdwPtr, dir, c, copyLines, pixLines);
ELSIF c.w > 0
THEN
SetClip (vdi, c, TRUE);
hdlDraw (wdw, vdi, special, c);
END;
ClipWork (wdwPtr);
UNTIL ~RectList (wdw, 1, work);
hdlUpdate (wdw, vdi, special, FALSE);
END;
ELSE
(* komplett neuzeichnen *)
updateWdw (wdwPtr, wdwWork);
END;
END (* WITH wdwPtr^ DO *);
END scrollWdw;
PROCEDURE scrollLR (wdwPtr : ptrWdwSlot; dir : INTEGER; amount : INTEGER);
VAR copy : MagicVDI.tBigPxyArray;
fill : MagicVDI.tPxyArray;
work,
c,
clip : Rectangle;
pscrMFDB,
pdesMFDB : MagicVDI.MFDB;
BEGIN
pscrMFDB.fdAddr := NIL;
pdesMFDB.fdAddr := NIL;
WITH wdwPtr^ DO
IF isIcon OR isHidden THEN RETURN END;
IF amount < wdwWork.w
THEN
(* Rechteckliste abfragen *)
IF RectList (wdw, 0, work)
THEN
hdlUpdate (wdw, vdi, special, TRUE);
REPEAT
(* kleinsten Redrawbereich bestimmen *)
c := RectFuncs.ClipRect (work, deskSize);
c := RectFuncs.ClipRect (c, wdwWork);
IF (c.w > 0) THEN
ClipWork (wdwPtr);
IF c.w > amount
THEN
IF dir = LEFT THEN
WITH c DO
copy[0] := x;
copy[1] := y;
copy[2] := BinOps.HigherInt(x, x+w-1-amount);
copy[3] := y+h-1;
copy[4] := x+amount;
copy[5] := y;
copy[6] := x+w-1;
copy[7] := y+h-1;
END;
ELSE
WITH c DO
copy[0] := x+amount;
copy[1] := y;
copy[2] := x+w-1;
copy[3] := y+h-1;
copy[4] := x;
copy[5] := y;
copy[6] := BinOps.HigherInt (x, x+w-1-amount);
copy[7] := y+h-1;
END;
END;
MagicVDI.CopyRasterOpaque(vdi, 3, copy, pscrMFDB, pdesMFDB);
END;
clip := c;
(* Redrawbereich berechnen *)
WITH c DO
clip.y := y;
clip.h := h;
IF dir = LEFT
THEN
clip.x := x;
clip.w := BinOps.LowerInt (amount + pixOff, w);
ELSE
clip.x := BinOps.HigherInt (x, x+w-1-amount);
clip.w := c.x + c.w - clip.x;
END;
END;
(*
IF dir = LEFT THEN
WITH c DO
fill[0] := x; fill[1] := y;
fill[2] := x+amount+pixOff-1; fill[3] := y+h-1;
END;
IF fill[2] > c.x+c.w-1
THEN fill[2] := c.x+c.w-1
END;
ELSE
WITH c DO
fill[0] := BinOps.HigherInt (x, x+w-1-amount);
fill[1] := y;
fill[2] := x+w-1;
fill[3] := y+h-1;
END;
END;
MagicVDI.FillRectangle(vdi, fill);
IF (fill[0]-2 <= wdwWork.x) THEN
INC (fill[0], pixOff);
IF fill[0] > c.x+c.w-1
THEN fill[0] := c.x+c.w-1
END;
END;
clip.x := fill[0];
clip.y := fill[1];
clip.w := fill[2]-fill[0]+1;
clip.h := fill[3]-fill[1]+1;
*)
SetClip (vdi, clip, TRUE);
hdlDraw (wdw, vdi, special, clip);
(* Linken Rand lschen *)
IF (c.x-pixOff <= wdwWork.x)
THEN
(* pixOff ausfllen *)
IF pixOff > 0
THEN
WITH c DO
fill[0] := wdwWork.x; fill[1] := y;
fill[2] := wdwWork.x+pixOff-1; fill[3] := y+h-1;
END;
ClipWork (wdwPtr);
MagicVDI.FillRectangle(vdi, fill);
END;
END;
END;
UNTIL ~RectList (wdw, 1, work);
hdlUpdate (wdw, vdi, special, FALSE);
END;
ClipWork (wdwPtr);
ELSE
updateWdw (wdwPtr, wdwWork);
END;
END;
END scrollLR;
(*====================================================*
* *
* High-Level-Funktionen *
* *
*====================================================*)
(* Sliderberechnungen *)
PROCEDURE CalcVSlider (wdwPtr : ptrWdwSlot);
VAR r : REAL;
a, b : LONGINT;
vslSize : INTEGER;
vslPos : INTEGER;
vslLong : LONGINT;
BEGIN
WITH wdwPtr^ DO
IF ~(MagicAES.VSLIDE IN comps) OR isIcon OR isHidden THEN RETURN END;
(* Gre berechnen *)
a := (document.h+1) * yFactor;
b := LONG(wdwWork.h);
IF a > 0 THEN
r := 1000.0 * (FLOAT (b)/FLOAT(a));
IF (r > 1000.0) OR (r < 0.0) THEN r := 1000.0 END;
ELSE
r := 1000.0;
END;
vslSize := VAL (INTEGER, TRUNC(r));
(* Position berechnen *)
IF document.y = 0
THEN
vslPos := 0
ELSE a := document.y * yFactor;
b := ((document.h+1) * yFactor) - LONG(wdwWork.h);
IF b > 0 THEN
vslLong := VAL (LONGINT,1000.0 * (FLOAT (a) / FLOAT (b)));
IF (vslLong > 1000) OR (vslLong < 0) THEN vslPos := 1000
ELSE
vslPos := VAL (INTEGER, SHORT( vslLong));
END;
ELSE
vslPos := 1000;
END;
END;
IF vslSize # VslSize THEN
MagicAES.WindSet (wdw, MagicAES.WFVSLSIZE, Rectangle {vslSize, 0,0,0});
VslSize := vslSize;
END;
IF vslPos # VslPos THEN
MagicAES.WindSet (wdw, MagicAES.WFVSLIDE, Rectangle {vslPos, 0,0,0});
VslPos := vslPos;
END;
END;
END CalcVSlider;
PROCEDURE CalcHSlider (wdwPtr : ptrWdwSlot);
VAR r : REAL;
a, b : LONGINT;
hslSize : INTEGER;
hslPos : INTEGER;
hslLong : LONGINT;
BEGIN
WITH wdwPtr^ DO
IF ~(MagicAES.HSLIDE IN comps) OR isIcon OR isHidden THEN RETURN END;
(* Gre berechnen *)
a := (document.w+1) * xFactor;
b := LONG(wdwWork.w);
IF a > 0
THEN
r := 1000.0 * (FLOAT (b)/FLOAT(a));
IF (r > 1000.0) OR (r < 0.0) THEN r := 1000.0 END;
ELSE
r := 1000.0;
END;
hslSize := VAL (INTEGER, TRUNC(r));
(* Position berechnen *)
IF document.x = 0
THEN
hslPos := 0
ELSE
a := document.x * xFactor;
b := ((document.w+1) * xFactor) - LONG(wdwWork.w);
IF b > 0 THEN
hslLong := VAL (LONGINT,1000.0 * (FLOAT (a) / FLOAT (b)));
IF (hslLong > 1000) OR (hslLong < 0) THEN
hslPos := 1000
ELSE
hslPos := VAL (INTEGER, SHORT( hslLong ) );
END;
ELSE
hslPos := 1000;
END;
END;
IF hslSize # HslSize THEN
MagicAES.WindSet (wdw, MagicAES.WFHSLSIZE, Rectangle {hslSize, 0,0,0});
HslSize := hslSize;
END;
IF hslPos # HslPos THEN
MagicAES.WindSet (wdw, MagicAES.WFHSLIDE, Rectangle {hslPos, 0,0,0});
HslPos := hslPos;
END;
END;
END CalcHSlider;
(* High-Level Scroll-Funktionen *)
PROCEDURE scrollUp (wdwPtr : ptrWdwSlot; lines : INTEGER);
VAR oldStart : LONGINT;
BEGIN
WITH wdwPtr^ DO
IF document.y > 0 THEN
oldStart := document.y;
DEC (document.y, LONG(lines) * minScrollH);
document.y := BinOps.HigherLInt (0, document.y);
setNewWdw (wdw, vdi, special, document, TRUE);
scrollWdw (wdwPtr, UP, SHORT((oldStart - document.y)*yFactor));
CalcVSlider (wdwPtr);
END;
END;
END scrollUp;
PROCEDURE scrollDown (wdwPtr : ptrWdwSlot; lines : INTEGER);
VAR oldStart : LONGINT;
BEGIN
WITH wdwPtr^ DO
IF document.y + pageH < document.h THEN
oldStart := document.y;
INC (document.y, LONG(lines) * minScrollH);
document.y := BinOps.LowerLInt (document.y, document.h - pageH);
setNewWdw (wdw, vdi, special, document, TRUE);
scrollWdw (wdwPtr, DOWN, SHORT((document.y - oldStart)*yFactor));
CalcVSlider (wdwPtr);
END;
END;
END scrollDown;
PROCEDURE scrollLeft (wdwPtr : ptrWdwSlot; cols : INTEGER);
VAR oldStart : LONGINT;
BEGIN
WITH wdwPtr^ DO
IF document.x > 0
THEN
oldStart := document.x;
DEC (document.x, LONG(cols) * minScrollW);
document.x := BinOps.HigherLInt (0, document.x);
setNewWdw (wdw, vdi, special, document, TRUE);
scrollLR (wdwPtr, LEFT, SHORT(xFactor*(oldStart-document.x)));
CalcHSlider (wdwPtr);
END;
END;
END scrollLeft;
PROCEDURE scrollRight (wdwPtr : ptrWdwSlot; cols : INTEGER);
VAR oldStart : LONGINT;
BEGIN
WITH wdwPtr^ DO
IF document.x + pageW < document.w - 1 THEN
oldStart := document.x;
INC (document.x, LONG(cols) * minScrollW);
document.x := BinOps.LowerLInt (document.w - pageW, document.x);
setNewWdw (wdw, vdi, special, document, TRUE);
scrollLR (wdwPtr, RIGHT, SHORT(xFactor*(document.x - oldStart)));
CalcHSlider (wdwPtr);
END;
END;
END scrollRight;
PROCEDURE pageUp (wdwPtr : ptrWdwSlot; pages : INTEGER);
VAR oldStart : LONGINT;
BEGIN
WITH wdwPtr^ DO
IF document.y > 0 THEN
oldStart := document.y;
DEC (document.y, pageH*LONG(pages));
document.y := BinOps.HigherLInt (0, document.y);
setNewWdw (wdw, vdi, special, document, TRUE);
scrollWdw (wdwPtr, UP, SHORT((oldStart - document.y)*yFactor));
CalcVSlider (wdwPtr);
END;
END;
END pageUp;
PROCEDURE pageDown (wdwPtr : ptrWdwSlot; pages : INTEGER);
VAR oldStart : LONGINT;
BEGIN
WITH wdwPtr^ DO
IF document.y + pageH < document.h THEN
oldStart := document.y;
INC (document.y, pageH*LONG(pages));
document.y := BinOps.LowerLInt(document.y , document.h-pageH);
setNewWdw (wdw, vdi, special, document, TRUE);
scrollWdw (wdwPtr, DOWN, SHORT((document.y - oldStart)*yFactor));
CalcVSlider (wdwPtr);
END;
END;
END pageDown;
PROCEDURE pageLeft (wdwPtr : ptrWdwSlot; pages : INTEGER);
VAR oldStart : LONGINT;
BEGIN
WITH wdwPtr^ DO
IF document.x > 0 THEN
oldStart := document.x;
DEC (document.x, pageW*LONG(pages));
document.x := BinOps.HigherLInt (0, document.x);
setNewWdw (wdw, vdi, special, document, TRUE);
scrollLR (wdwPtr, LEFT, SHORT(xFactor* (oldStart-document.x)));
CalcHSlider (wdwPtr);
END;
END;
END pageLeft;
PROCEDURE pageRight (wdwPtr : ptrWdwSlot; pages : INTEGER);
VAR oldStart : LONGINT;
BEGIN
WITH wdwPtr^ DO
IF document.x + pageW < document.w - 1 THEN
oldStart := document.x;
INC (document.x, pageW*LONG(pages));
document.x := BinOps.LowerLInt (document.x, document.w - pageW);
setNewWdw (wdw, vdi, special, document, TRUE);
scrollLR (wdwPtr, RIGHT, SHORT(xFactor*(document.x - oldStart)));
CalcHSlider (wdwPtr);
END;
END;
END pageRight;
PROCEDURE FindWindow (wdw : INTEGER) : ptrWdwSlot;
VAR wdwPtr : ptrWdwSlot;
BEGIN
wdwPtr := windows;
WHILE (wdwPtr # NIL) & (wdwPtr^.wdw # wdw) DO wdwPtr := wdwPtr^.next END;
RETURN wdwPtr;
END FindWindow;
PROCEDURE FindTop () : ptrWdwSlot;
VAR wdw , vdi : INTEGER;
BEGIN
GetTopWindow (wdw, vdi);
RETURN FindWindow (wdw);
END FindTop;
(*====================================================*
* *
* Event-Handling-Funktionen *
* *
*====================================================*)
PROCEDURE untopWdw (wdwPtr : ptrWdwSlot);
BEGIN
WITH wdwPtr^ DO
IF ~isTop THEN RETURN END;
isTop := FALSE;
IF hdlUntop # untopProc(NIL) THEN
hdlUntop (wdw, vdi, special);
END;
END;
END untopWdw;
PROCEDURE topWdw (wdwPtr : ptrWdwSlot; doTop : BOOLEAN);
VAR r : Rectangle;
oldTopPtr : ptrWdwSlot;
BEGIN
(* altes Top-Window feststellen *)
IF (onlyOneTop >= 0) & (wdwPtr^.wdw # onlyOneTop) THEN
(* onlyOneTopWdw toppen *)
wdwPtr := FindWindow (onlyOneTop);
IF wdwPtr # NIL
THEN
topWdw (wdwPtr, doTop);
END;
RETURN
END;
WITH wdwPtr^ DO
oldTopPtr := FindTop ();
IF (oldTopPtr # NIL) & doTop & (oldTopPtr^.wdw # wdw) THEN
(* Altes Topwindow untoppen *)
untopWdw (oldTopPtr);
END;
IF hdlTop (wdw, vdi, special)
THEN
IF doTop THEN
MagicAES.WindSet (wdw, MagicAES.WFTOP, r);
END;
theTopWindow := wdw;
NewWindowIsTop (wdw, mtAppl.ApplIdent);
isTop := TRUE;
END;
END;
END topWdw;
PROCEDURE BottomOfQueue(VAR item, apid: INTEGER); FORWARD;
PROCEDURE TopLastWindow(); FORWARD;
PROCEDURE BringToBottom (wdw, apId : INTEGER); FORWARD;
PROCEDURE backdropWdw (wdwPtr : ptrWdwSlot);
VAR r : Rectangle;
BEGIN
WITH wdwPtr^ DO
IF (onlyOneTop >= 0) & (wdw = onlyOneTop)
THEN
(* Alle nach hinten schicken *)
ELSE
untopWdw (wdwPtr);
MagicAES.WindSet (wdw, MagicAES.WFMBACKDROP, r);
BringToBottom (wdw, mtAppl.ApplIdent);
END;
END;
END backdropWdw;
PROCEDURE bottomWdw (wdwPtr : ptrWdwSlot);
VAR r : Rectangle;
BEGIN
WITH wdwPtr^ DO
IF (onlyOneTop >= 0) & (wdw = onlyOneTop)
THEN
(* Alle nach hinten schicken *)
ELSE
untopWdw (wdwPtr);
MagicAES.WindSet (wdw, MagicAES.WFBOTTOM, r);
BringToBottom (wdw, mtAppl.ApplIdent);
(*
BottomOfQueue (r.x, r.y);
IF r.x # wdw
THEN
TopLastWindow();
END;
*)
END;
END;
END bottomWdw;
PROCEDURE SendRedraw (win: INTEGER; r : Rectangle); FORWARD;
PROCEDURE moveSizeWdw (wdwPtr : ptrWdwSlot; sized, fulled : BOOLEAN; newSize : Rectangle; adaptPos : BOOLEAN);
(* Wird aufgerufen, wenn das Fenster verschoben
* oder in der Gre verndert wird.
*)
VAR docChanged : BOOLEAN;
oldVal : LONGINT;
idx : INTEGER;
again : BOOLEAN;
BEGIN
WITH wdwPtr^ DO
IF ~isIcon
THEN
newSize.w := BinOps.HigherInt (newSize.w, minWindWidth);
newSize.h := BinOps.HigherInt (newSize.h, minWindHeight);
(* Workarea aus neuer Gre berechnen *)
MagicAES.WindCalc (MagicAES.WCWORK, comps, newSize, wdwWork);
IF snap
THEN
hdlSnap (wdw, vdi, special, wdwWork);
END;
(* Jetzt neue Auengre berechnen *)
MagicAES.WindCalc (MagicAES.WCBORDER, comps, wdwWork, newSize);
IF sized & ~fulled THEN isFull := FALSE; END;
END;
IF ~isHidden
THEN
idx := 1;
LOOP
MagicAES.WindSet(wdw, MagicAES.WFCURRXYWH, newSize);
again := FALSE;
IF ~isIcon
THEN
MagicAES.WindGet(wdw, MagicAES.WFCURRXYWH, wdwCurr);
IF (wdwCurr.w # newSize.w)
THEN
INC (newSize.w, idx*mtAppl.CharWidth);
again := TRUE;
END;
IF (wdwCurr.h # newSize.h)
THEN
INC (newSize.h, idx*mtAppl.CharHeight);
again := TRUE;
END;
IF again
THEN
INC (idx);
(* Workarea aus neuer Gre berechnen *)
MagicAES.WindCalc (MagicAES.WCWORK, comps, newSize, wdwWork);
IF snap
THEN
hdlSnap (wdw, vdi, special, wdwWork);
END;
(* Jetzt neue Auengre berechnen *)
MagicAES.WindCalc (MagicAES.WCBORDER, comps, wdwWork, newSize);
ELSE
EXIT
END;
ELSE
EXIT
END;
END;
END;
wdwCurr := newSize;
IF ~isIcon & ~isHidden
THEN
(* Neuen Arbeitsbereich holen *)
wdwGetScroll (wdw, vdi, special, wdwWork);
IF sized & adaptPos THEN
(* Falls Dokument ganz hineinpat, neu positionieren *)
docChanged := FALSE;
IF document.y > 0
THEN
IF LONG (wdwWork.h) DIV yFactor + document.y > document.h
THEN
oldVal := document.y;
document.y := BinOps.HigherLInt (0, document.h - (LONG(wdwWork.h) DIV yFactor)+1);
docChanged := oldVal # document.y;
END;
END;
IF document.x > 0
THEN
IF LONG (wdwWork.w) DIV xFactor + document.x > document.w
THEN
oldVal := document.x;
document.x := BinOps.HigherLInt (0, document.w - (LONG (wdwWork.w) DIV xFactor));
docChanged := docChanged OR (oldVal # document.x);
END;
END;
IF docChanged
THEN
setNewWdw (wdw, vdi, special, document, FALSE);
(* Redraw auslsen ber Fensterbereich *)
SendRedraw (wdw, newSize);
END;
(* Slider neu berechnen *)
CalcVSlider (wdwPtr);
CalcHSlider (wdwPtr);
END;
END;
END;
END moveSizeWdw;
PROCEDURE fullWdw (wdwPtr : ptrWdwSlot);
(* Wird aufgerufen, wenn fr das Fenster ein FULL-Event
* auftrat. Gegebenenfalls wird noch die Snap-Prozedur
* aufgerufen.
* Die Slider werden neu berechnet.
*)
VAR newSize : Rectangle;
BEGIN
WITH wdwPtr^ DO
IF isIcon OR isHidden OR (wdwDial # NIL) THEN RETURN END;
IF isFull
THEN
newSize := wdwLast;
ELSE
newSize := wdwFull;
wdwLast := wdwCurr;
END;
isFull := ~isFull;
(* Jetzt der Einfachheit halber einfach moveSize aufrufen *)
moveSizeWdw (wdwPtr, TRUE, TRUE, newSize, TRUE);
END;
END fullWdw;
PROCEDURE arrowedWdw (wdwPtr : ptrWdwSlot; what : CARDINAL; amount: INTEGER);
VAR button : BITSET;
scrollProc : PROCEDURE (ptrWdwSlot, INTEGER);
BEGIN
CASE what OF
0 : scrollProc := pageUp; |
1 : scrollProc := pageDown; |
2 : scrollProc := scrollUp; |
3 : scrollProc := scrollDown; |
4 : scrollProc := pageLeft; |
5 : scrollProc := pageRight; |
6 : scrollProc := scrollLeft; |
7 : scrollProc := scrollRight; |
ELSE
END;
IF (what >= 0) & (what <= 7) THEN
WITH wdwPtr^ DO
hdlUpdate (wdw, vdi, special, TRUE);
scrollProc (wdwPtr, amount);
(*
REPEAT
scrollProc (wdwPtr, 1);
MagicAES.GrafMkstate(v.int, v.int, button, v.bset);
UNTIL ~(0 IN button);
*)
hdlUpdate (wdw, vdi, special, FALSE);
END;
END;
END arrowedWdw;
PROCEDURE vSlideWdw (wdwPtr : ptrWdwSlot; where: CARDINAL);
VAR oldStart : LONGINT;
newStart : LONGINT;
BEGIN
WITH wdwPtr^ DO
oldStart := document.y; (* Start des Ausschnittes merken *)
IF (document.h+1) * yFactor > LONG(wdwWork.h) THEN
IF where = 1000 THEN
document.y := ((document.h+1)*yFactor-LONG(wdwWork.h)) DIV yFactor;
ELSE
document.y := (VAL(LONGINT,where)*(((document.h+1)*yFactor)-LONG(wdwWork.h)) DIV 1000L) DIV yFactor;
END;
IF oldStart # document.y THEN
hdlUpdate (wdw, vdi, special, TRUE);
setNewWdw (wdw, vdi, special, document, TRUE);
IF oldStart < document.y
THEN
scrollWdw (wdwPtr, DOWN, (document.y-oldStart) * yFactor);
ELSE
scrollWdw (wdwPtr, UP, (oldStart-document.y) * yFactor);
END;
hdlUpdate (wdw, vdi, special, FALSE);
END
END;
CalcVSlider (wdwPtr);
END
END vSlideWdw;
PROCEDURE hSlideWdw (wdwPtr : ptrWdwSlot; where : INTEGER);
VAR oldOff,
newOff : LONGINT;
BEGIN
WITH wdwPtr^ DO
oldOff := document.x;
IF (document.w+1) * xFactor > LONG(wdwWork.w) THEN
IF where = 1000 THEN
newOff := (document.w+1) * xFactor - LONG(wdwWork.w);
ELSE
newOff := LONG(where) * ((document.w+1) * xFactor - LONG(wdwWork.w)) DIV 1000L;
END;
newOff := BinOps.LowerLInt (newOff, ((document.w+1) * xFactor)-LONG(wdwWork.w));
IF newOff # oldOff THEN
hdlUpdate (wdw, vdi, special, TRUE);
document.x := newOff DIV xFactor;
setNewWdw (wdw, vdi, special, document, TRUE);
IF oldOff < newOff
THEN
scrollLR (wdwPtr, RIGHT, SHORT(newOff-oldOff));
ELSE
scrollLR (wdwPtr, LEFT, SHORT(oldOff-newOff));
END;
hdlUpdate (wdw, vdi, special, FALSE);
END;
END;
CalcHSlider (wdwPtr);
END
END hSlideWdw;
PROCEDURE hideWdw (wdwPtr: ptrWdwSlot);
BEGIN
WITH wdwPtr^ DO
(* Fenster schlieen *)
MagicAES.WindClose (wdw);
IF hdlHide # hideProc (NIL) THEN hdlHide (wdw, vdi, special, TRUE); END;
isHidden := TRUE;
END;
END hideWdw;
PROCEDURE showWdw (wdwPtr : ptrWdwSlot; doUntop: BOOLEAN);
VAR bits : INTEGER;
r : Rectangle;
oldTop: ptrWdwSlot;
BEGIN
WITH wdwPtr^ DO
(* Altes TopWindow untoppen *)
oldTop := FindTop();
IF ((oldTop # NIL) & doUntop) THEN
untopWdw (oldTop);
END;
(* Fenster wieder ffnen *)
isHidden := FALSE;
IF hdlHide # hideProc (NIL) THEN hdlHide (wdw, vdi, special, FALSE); END;
MagicAES.WindOpen (wdw, wdwCurr);
IF hdlTop (wdw, vdi, special) THEN END;
isTop := TRUE;
(* Die Slider wieder richtig setzen *)
IF (MagicAES.VSLIDE IN comps) THEN
MagicAES.WindSet (wdw, MagicAES.WFVSLSIZE, Rectangle {VslSize, 0,0,0});
MagicAES.WindSet (wdw, MagicAES.WFVSLIDE, Rectangle {VslPos, 0,0,0});
END;
IF (MagicAES.HSLIDE IN comps) THEN
MagicAES.WindSet (wdw, MagicAES.WFHSLSIZE, Rectangle {HslSize, 0,0,0});
MagicAES.WindSet (wdw, MagicAES.WFHSLIDE, Rectangle {HslPos, 0,0,0});
END;
(* Jetzt noch abfragen, ob das Fenster iconifiziert ist *)
isIcon := FALSE;
IF (MagicAES.ApplGetinfo (MagicAES.AEWINDOWS, bits, v.int, v.int, v.int) = 1)
& (MagicSys.Bit7 IN BITSET(bits))
THEN
MagicAES.WindGet (wdw, MagicAES.WFICONIFY, r);
isIcon := r.x = 1;
END;
END;
END showWdw;
PROCEDURE closeWdw (wdwPtr : ptrWdwSlot; force : BOOLEAN) : BOOLEAN;
BEGIN
(* CloseProc aufrufen *)
WITH wdwPtr^ DO
IF ~hdlClose (wdw, vdi, special, force)
THEN
RETURN FALSE
END;
(* Fenster schlieen *)
IF ~isHidden
THEN
MagicAES.WindClose (wdw);
END;
MagicAES.WindDelete (wdw);
WindowIsClosed (wdw);
(* Workstation schlieen *)
IF vdi > 0
THEN
mtAppl.CloseWorkstation (vdi);
vdi := -1;
END;
END;
(* Aus der Liste aushngen *)
IF wdwPtr^.next # NIL
THEN
wdwPtr^.next^.prev := wdwPtr^.prev;
END;
IF wdwPtr^.prev # NIL
THEN
wdwPtr^.prev^.next := wdwPtr^.next;
END;
IF windows = wdwPtr
THEN
windows := wdwPtr^.next;
END;
IF wdwPtr^.onlyTop
THEN
onlyOneTop := wdwPtr^.lastOnlyTop;
END;
DISPOSE (wdwPtr);
(* Neues TopWindow toppen (WMNEWTOP bzw. WMONTOP in AES 4.0 *)
wdwPtr := FindTop ();
IF (wdwPtr # NIL) (* & ~multiTOS *)
THEN
topWdw (wdwPtr, FALSE);
END;
RETURN TRUE
END closeWdw;
PROCEDURE iconifyWdw (wdwPtr : ptrWdwSlot; iconRect : Rectangle);
BEGIN
WITH wdwPtr^ DO
IF isIcon THEN RETURN END;
isIcon := TRUE;
wdwIcon := wdwCurr;
MagicAES.WindSet (wdw, MagicAES.WFICONIFY, iconRect);
MagicAES.WindGet (wdw, MagicAES.WFCURRXYWH, wdwCurr);
IF hdlHide # hideProc (NIL) THEN hdlHide (wdw, vdi, special, TRUE); END;
FullRedrawWdw (wdw);
END;
END iconifyWdw;
PROCEDURE unIconifyWdw (wdwPtr : ptrWdwSlot; wdwRect : Rectangle);
VAR p : ptrWdwSlot;
curr : Rectangle;
BEGIN
WITH wdwPtr^ DO
IF allIconified
THEN
(* alle anderen versteckten, iconifizierten wieder zeigen bis auf
* dieses wdw!
*)
p := windows;
WHILE p # NIL DO
IF (p^.wdw # wdwPtr^.wdw) &
p^.isIcon & p^.isHidden
THEN
(* ist nicht dieses Window *)
showWdw (p, FALSE);
MagicAES.WindGet (p^.wdw, MagicAES.WFCURRXYWH, curr);
moveSizeWdw (p, FALSE, FALSE, curr, FALSE);
END;
p := p^.next;
END;
allIconified := FALSE;
END;
IF ~isIcon THEN RETURN END;
isIcon := FALSE;
MagicAES.WindSet (wdw, MagicAES.WFUNICONIFY, wdwRect);
MagicAES.WindGet (wdw, MagicAES.WFCURRXYWH, wdwCurr);
IF hdlHide # hideProc(NIL) THEN hdlHide (wdw, vdi, special, FALSE); END;
moveSizeWdw (wdwPtr, FALSE, FALSE, wdwCurr,FALSE);
IF (MagicAES.VSLIDE IN wdwPtr^.comps) THEN
MagicAES.WindSet (wdw, MagicAES.WFVSLSIZE, Rectangle {VslSize, 0,0,0});
MagicAES.WindSet (wdw, MagicAES.WFVSLIDE, Rectangle {VslPos, 0,0,0});
END;
IF (MagicAES.HSLIDE IN wdwPtr^.comps) THEN
MagicAES.WindSet (wdw, MagicAES.WFHSLSIZE, Rectangle {HslSize, 0,0,0});
MagicAES.WindSet (wdw, MagicAES.WFHSLIDE, Rectangle {HslPos, 0,0,0});
END;
topWdw (wdwPtr, TRUE);
SendTop (wdwPtr^.wdw, mtAppl.ApplIdent);
END;
END unIconifyWdw;
PROCEDURE allIconifyWdw (wdwPtr : ptrWdwSlot; iconRect : Rectangle);
VAR p : ptrWdwSlot;
BEGIN
(* Das angeklickte Window wird iconifiziert und alle anderen werden versteckt.
* Schon versteckte werden beim uniconify nicht mit aufgedeckt!
*)
p := windows;
WHILE p # NIL DO
IF ~p^.isHidden (* & ~p^.isIcon *) & (p^.wdw # wdwPtr^.wdw)
THEN
(* ist nicht dieses Window *)
p^.wdwIcon := p^.wdwCurr;
hideWdw (p);
p^.isIcon := TRUE;
ELSIF ~p^.isHidden (* & ~p^.isIcon *) & (p^.wdw = wdwPtr^.wdw)
THEN
iconifyWdw (p, iconRect);
END;
p := p^.next;
END;
allIconified := TRUE;
END allIconifyWdw;
(* Diese Prozedur handelt den ganzen Drag-Drop Kram nach einem Event *)
PROCEDURE HandleDragDrop (mess: ADDRESS);
CONST cPipeName = 'u:\pipe\dragdrop.';
VAR access : POINTER TO RECORD
messId : INTEGER;
apId : INTEGER;
over : INTEGER;
tWin : INTEGER;
mx : INTEGER;
my : INTEGER;
kshift : INTEGER;
pext0,
pext1 : CHAR;
END;
buff : ARRAY [0..MagicAES.DD_EXTSIZE] OF CHAR;
hdr : POINTER TO RECORD
dtype : ARRAY [0..3] OF CHAR;
dlen : LONGCARD;
dname : ARRAY [0..2047] OF CHAR;
END;
oldsigpipe : ADDRESS;
i : INTEGER;
pext : ARRAY [0..3] OF CHAR;
exts : ARRAY [0..MagicAES.DD_EXTSIZE - 1] OF CHAR;
pname : ARRAY [0..255] OF CHAR;
phdl : INTEGER;
data : ADDRESS;
count : LONGCARD;
hdrLen : CARDINAL;
wdw : INTEGER;
PROCEDURE restore();
BEGIN
(* Alten Sigpipe-Handler wieder installieren *)
IF phdl > 0 THEN v.int := MagicDOS.Fclose (phdl); END;
(* Speicher wird hier freigegeben *)
IF data # NIL THEN DEALLOCATE (data, 0); END;
IF hdr # NIL THEN DEALLOCATE (hdr, 0); END;
oldsigpipe := Mintbind.Psignal (Mintbind.SIGPIPE, oldsigpipe);
END restore;
BEGIN
phdl := -1;
hdr := NIL;
data := NIL;
(* Erstmal neuen Signalhandler installieren *)
oldsigpipe := Mintbind.Psignal (Mintbind.SIGPIPE, Mintbind.SIG_IGN);
access := mess;
WITH access^ DO
pext[0] := pext0;
pext[1] := pext1;
pext[2] := 0C;
Strings.Assign (cPipeName, pname, v.bool);
Strings.Append (pext, pname, v.bool);
phdl := MagicDOS.Fopen (pname, {MagicDOS.ReadWrite});
IF phdl < 0 THEN restore(); RETURN END;
(* Pipe ist offen, jetzt erstmal beim Windowhandler anfragen, ob
* das Targetfenster DragDrop versteht
*)
IF ~WdwDoesDragDrop (tWin)
THEN
(* Das Fenster kann kein DragDrop, also nehmen wir auch nichts an!
*)
buff[0] := CHR(MagicAES.DD_NAK);
count := 1;
MagicDOS.Fwrite (phdl, count, ADR(buff));
(* Uns ist ziemlich egal, ob das geklappt hat, wir schlieen die Pipe
* jetzt wieder
*)
v.int := MagicDOS.Fclose (phdl);
restore();
RETURN
END;
(* Ok, das Fenster kann Drag & Drop, also jetzt mal die Extensions anfordern
*)
wdw := tWin;
WdwDDGetExts (wdw, exts);
(* Umkopieren *)
FOR i := 0 TO SHORT(MagicAES.DD_EXTSIZE) - 1 DO
buff[i+1] := exts[i];
END;
buff[0] := CHR (MagicAES.DD_OK);
(* Jetzt DD_OK und Extensions in Pipe schreiben *)
count := MagicAES.DD_EXTSIZE + 1;
MagicDOS.Fwrite (phdl, count, ADR(buff));
IF count # (MagicAES.DD_EXTSIZE + 1)
THEN
(* Fehler aufgetreten, Pipe schlieen und raus hier. *)
restore ();
RETURN
END;
LOOP
(* Jetzt 2 Bytes aus der Pipe lesen (Headerlnge) *)
count := 2;
MagicDOS.Fread (phdl, count, ADR(hdrLen));
IF count # 2
THEN
(* Fehler aufgetreten, Pipe schlieen und raus hier. *)
EXIT
END;
(* Jetzt den Header lesen *)
ALLOCATE (hdr, hdrLen);
IF hdr = NIL
THEN
(* Kein Speicher frei! *)
EXIT
END;
(* Jetzt den Header lesen *)
count := hdrLen;
MagicDOS.Fread (phdl, count, hdr);
IF count # LONG(hdrLen)
THEN
(* Fehler aufgetreten, Pipe schlieen und raus hier. *)
EXIT
END;
(* Jetzt haben wir den Header, nachfragen, ob das akzeptiert wird *)
IF WdwDDAcceptData (wdw, hdr)
THEN
(* Speicher allozieren fr Daten *)
ALLOCATE (data, hdr^.dlen);
IF data = NIL
THEN
(* DD_NAK in Pipe schreiben und abbrechen *)
buff[0] := CHR (MagicAES.DD_NAK);
count := 1;
MagicDOS.Fwrite (phdl, count, ADR(buff));
EXIT
END;
(* DD_OK in Pipe schreiben *)
buff[0] := CHR (MagicAES.DD_OK);
count := 1;
MagicDOS.Fwrite (phdl, count, ADR(buff));
IF count # 1
THEN
EXIT
END;
(* Ok, jetzt haben wir auch einen Buffer fr die Daten,
* jetzt knnen wir die Daten aus der Pipe lesen
*)
count := hdr^.dlen;
MagicDOS.Fread (phdl, count, data);
IF count # hdr^.dlen
THEN
EXIT
END;
(* Jetzt die Daten an das Fenster bergeben *)
WdwDDWriteData (wdw, data, count);
(* Speicher wieder am Ende in restore freigeben *)
(* Das war's, Pipe wird am Ende geschlossen *)
EXIT
ELSE
(* DD_EXT in Pipe schreiben und wieder nach vorne *)
buff[0] := CHR (MagicAES.DD_EXT);
count := 1;
MagicDOS.Fwrite (phdl, count, ADR(buff));
END;
DEALLOCATE (hdr, 0);
END; (* LOOP *)
END;
restore();
END HandleDragDrop;
PROCEDURE MessageEvent (PBuff : ADDRESS) : BOOLEAN;
VAR mess : POINTER TO ARRAY[0..15] OF INTEGER;
wdwPtr : ptrWdwSlot;
voidO : BOOLEAN;
BEGIN
mess := PBuff;
wdwPtr := FindWindow (mess^[3]);
IF wdwPtr # NIL
THEN
WITH wdwPtr^ DO
CASE mess^[0] OF
MagicAES.WMREDRAW : updateWdw (wdwPtr, Rectangle {mess^[4], mess^[5], mess^[6], mess^[7]}); |
MagicAES.WMTOPPED : topWdw (wdwPtr, TRUE); |
MagicAES.WMCLOSED : voidO := closeWdw (wdwPtr, FALSE); |
MagicAES.WMFULLED : fullWdw (wdwPtr); |
MagicAES.WMARROWED : IF mess^[5] >= 0
THEN
arrowedWdw (wdwPtr, mess^[4], 1);
END;
IF mess^[5] < 0
THEN
(* erweiterte Scrollfunktionen von Winx *)
arrowedWdw (wdwPtr, mess^[4], -mess^[5])
END;
IF mess^[7] < 0
THEN
(* erweiterte Scrollfunktionen von Winx *)
arrowedWdw (wdwPtr, mess^[6], -mess^[7])
END;|
MagicAES.WMHSLID : hSlideWdw (wdwPtr, mess^[4]); |
MagicAES.WMVSLID : vSlideWdw (wdwPtr, mess^[4]); |
MagicAES.WMSIZED : moveSizeWdw (wdwPtr, TRUE, FALSE, Rectangle {mess^[4], mess^[5], mess^[6], mess^[7]}, TRUE); |
MagicAES.WMMOVED : moveSizeWdw (wdwPtr, FALSE, FALSE, Rectangle {mess^[4], mess^[5], mess^[6], mess^[7]}, FALSE); |
MagicAES.WMNEWTOP : topWdw (wdwPtr, FALSE); |
MagicAES.WMUNTOPPED: untopWdw (wdwPtr); |
MagicAES.WMONTOP : topWdw (wdwPtr, FALSE); |
MagicAES.WMBDROPPED: backdropWdw (wdwPtr); |
MagicAES.WMBOTTOMED: bottomWdw (wdwPtr); |
MagicAES.WMICONIFY : iconifyWdw (wdwPtr, Rectangle {mess^[4], mess^[5], mess^[6], mess^[7]}); |
MagicAES.WMUNICONIFY : unIconifyWdw (wdwPtr, Rectangle {mess^[4], mess^[5], mess^[6], mess^[7]}); |
MagicAES.WMALLICONIFY : allIconifyWdw (wdwPtr, Rectangle {mess^[4], mess^[5], mess^[6], mess^[7]}); |
MagicAES.AP_DRAGDROP : HandleDragDrop (PBuff); |
ELSE
RETURN FALSE;
END;
RETURN TRUE;
END
ELSE
(* Feststellen, ob ein anderes Fenster getoppt wurde *)
IF mess^[0] = MagicAES.WMTOPPED
THEN
(* Feststellen, ob eines unserer Fenster Topwindow war
* und ggf. untoppedHdler aufrufen
*)
(* altes Top-Window feststellen *)
wdwPtr := FindTop ();
IF wdwPtr # NIL THEN
WITH wdwPtr^ DO
isTop := FALSE;
IF hdlUntop # untopProc (NIL)
THEN
hdlUntop (wdw, vdi, special);
END;
END;
END;
END;
END;
RETURN FALSE;
END MessageEvent;
TYPE pageProc = PROCEDURE (ptrWdwSlot, INTEGER);
PROCEDURE scrollFunction (wdw : INTEGER; func : pageProc; parm : INTEGER);
VAR wdwPtr : ptrWdwSlot;
BEGIN
wdwPtr := FindWindow (wdw);
IF wdwPtr # NIL
THEN
WITH wdwPtr^ DO
hdlUpdate (wdw, vdi, special, TRUE);
func (wdwPtr, parm);
hdlUpdate (wdw, vdi, special, FALSE);
END;
END;
END scrollFunction;
(*====================================================*
* *
* Exportierte Funktionen *
* *
*====================================================*)
PROCEDURE PageUp (wdw : INTEGER);
BEGIN
scrollFunction (wdw, pageUp, 1);
END PageUp;
PROCEDURE PageDown (wdw : INTEGER);
BEGIN
scrollFunction (wdw, pageDown, 1);
END PageDown;
PROCEDURE PageLeft (wdw : INTEGER);
BEGIN
scrollFunction (wdw, pageLeft, 1);
END PageLeft;
PROCEDURE PageRight (wdw : INTEGER);
BEGIN
scrollFunction (wdw, pageRight, 1);
END PageRight;
PROCEDURE ScrollUp (wdw : INTEGER; lines : INTEGER);
BEGIN
scrollFunction (wdw, scrollUp, lines);
END ScrollUp;
PROCEDURE ScrollDown (wdw : INTEGER; lines : INTEGER);
BEGIN
scrollFunction (wdw, scrollDown, lines);
END ScrollDown;
PROCEDURE ScrollLeft (wdw : INTEGER; amount : INTEGER);
BEGIN
scrollFunction (wdw, scrollLeft, amount);
END ScrollLeft;
PROCEDURE ScrollRight (wdw : INTEGER; amount : INTEGER);
BEGIN
scrollFunction (wdw, scrollRight, amount);
END ScrollRight;
PROCEDURE WdwComps (wdw : INTEGER) : BITSET;
(* Liefert die Window-Elemente zurck
*)
VAR wdwPtr : ptrWdwSlot;
BEGIN
wdwPtr := FindWindow (wdw);
IF wdwPtr # NIL
THEN
RETURN wdwPtr^.comps;
END;
RETURN {};
END WdwComps;
PROCEDURE SnapWdw (wdw : INTEGER);
VAR wdwPtr : ptrWdwSlot;
BEGIN
wdwPtr := FindWindow (wdw);
IF wdwPtr # NIL
THEN
moveSizeWdw (wdwPtr, FALSE, FALSE, wdwPtr^.wdwCurr, FALSE);
END;
END SnapWdw;
PROCEDURE SetWdwSize (wdw : INTEGER; rect : Rectangle);
(* Setzt neue aktuelle Auengre fr das Fenster
*)
VAR wdwPtr : ptrWdwSlot;
BEGIN
wdwPtr := FindWindow (wdw);
IF wdwPtr # NIL
THEN
moveSizeWdw (wdwPtr, TRUE, FALSE, rect, FALSE);
END;
END SetWdwSize;
PROCEDURE GetWdwSize (wdw : INTEGER; VAR rect : Rectangle);
(* Erfragt aktuelle Auengre fr das Fenster
*)
VAR wdwPtr : ptrWdwSlot;
BEGIN
wdwPtr := FindWindow (wdw);
IF wdwPtr # NIL
THEN
IF wdwPtr^.isIcon
THEN
rect := wdwPtr^.wdwIcon;
ELSE
rect := wdwPtr^.wdwCurr;
END;
ELSE
MagicAES.WindGet (wdw, MagicAES.WFCURRXYWH, rect);
END;
END GetWdwSize;
PROCEDURE SetWdwWork (wdw : INTEGER; rect : Rectangle);
(* Setzt neue aktuelle Arbeitsflchengre fr das Fenster
*)
VAR wdwPtr : ptrWdwSlot;
BEGIN
wdwPtr := FindWindow (wdw);
IF wdwPtr # NIL
THEN
MagicAES.WindCalc (MagicAES.WCBORDER, wdwPtr^.comps, rect, rect);
moveSizeWdw (wdwPtr, TRUE, FALSE, rect, FALSE);
END;
END SetWdwWork;
PROCEDURE GetWdwWork (wdw : INTEGER; VAR rect : Rectangle);
(* Erfragt aktuelle Arbeitsflchengre fr das Fenster
*)
VAR wdwPtr : ptrWdwSlot;
BEGIN
wdwPtr := FindWindow (wdw);
IF wdwPtr # NIL
THEN
rect := wdwPtr^.wdwCurr;
MagicAES.WindCalc (MagicAES.WCWORK, wdwPtr^.comps, rect, rect);
ELSE
MagicAES.WindGet (wdw, MagicAES.WFWORKXYWH, rect);
END;
END GetWdwWork;
PROCEDURE SetDocumentParms (wdw : INTEGER; xFac, yFac: LONGINT);
(* Setzt die Parameter fr die Ausschnittsberechnung
*)
VAR wdwPtr : ptrWdwSlot;
BEGIN
wdwPtr := FindWindow (wdw);
IF wdwPtr # NIL
THEN
WITH wdwPtr^ DO
IF xFac # xFactor THEN xFactor := xFac; CalcHSlider (wdwPtr); END;
IF yFac # yFactor THEN yFactor := yFac; CalcVSlider (wdwPtr); END;
END;
END;
END SetDocumentParms;
PROCEDURE SetScrollParms (wdw : INTEGER; pgW, pgH, minScrW, minScrH : LONGINT);
(* Setzt die Parameter fr das Blttern im Dokument
*)
VAR wdwPtr : ptrWdwSlot;
BEGIN
wdwPtr := FindWindow (wdw);
IF wdwPtr # NIL
THEN
WITH wdwPtr^ DO
pageW := pgW;
pageH := pgH;
minScrollW := minScrW;
minScrollH := minScrH;
END;
END;
END SetScrollParms;
PROCEDURE GetScrollParms (wdw : INTEGER; VAR pgW, pgH, minScrW, minScrH : LONGINT);
(* Erfragt die Parameter fr das Blttern im Dokument
*)
VAR wdwPtr : ptrWdwSlot;
BEGIN
wdwPtr := FindWindow (wdw);
IF wdwPtr # NIL
THEN
WITH wdwPtr^ DO
pgW := pageW;
pgH := pageH;
minScrW := minScrollW;
minScrH := minScrollH;
END;
END;
END GetScrollParms;
PROCEDURE checkDocument (VAR document: LongRect);
BEGIN
WITH document DO
IF w < 0 THEN w := 0 END;
IF h < 0 THEN h := 0 END;
IF x > w THEN x := w END;
IF y > h THEN y := h END;
END;
END checkDocument;
PROCEDURE SetNewDocument (wdw : INTEGER; doc : LongRect; redraw: BOOLEAN);
(* Setzt die aktuellen Dokument-Parameter ohne automatisches Scrollen
* Wenn redraw = TRUE, wird ein Redraw ber das komplette Fenster ausgelst.
*)
VAR wdwPtr : ptrWdwSlot;
frame : Rectangle;
BEGIN
wdwPtr := FindWindow (wdw);
IF wdwPtr # NIL
THEN
WITH wdwPtr^ DO
IF isIcon OR isHidden THEN RETURN END;
document := doc;
(* Jetzt noch Check auf Gltigkeit *)
checkDocument (document);
CalcVSlider (wdwPtr);
CalcHSlider (wdwPtr);
IF redraw THEN
(* Workbereich berechnen, da in wdwWork nur der
* Scrollbereich steht *)
MagicAES.WindCalc (MagicAES.WCWORK, comps, wdwCurr, frame);
updateWdw (wdwPtr, frame);
END;
END;
END;
END SetNewDocument;
PROCEDURE SetWdwDocument (wdw : INTEGER; doc : LongRect);
(* Setzt die aktuellen Dokument-Parameter
*)
VAR wdwPtr : ptrWdwSlot;
oldDoc : LongRect;
fullRedraw : BOOLEAN;
BEGIN
wdwPtr := FindWindow (wdw);
IF wdwPtr # NIL
THEN
WITH wdwPtr^ DO
IF isIcon OR isHidden THEN RETURN END;
oldDoc := document;
document := doc;
(* Jetzt noch Check auf Gltigkeit *)
checkDocument (document);
fullRedraw := FALSE;
(* Jetzt Fenster ggf. scrollen *)
IF doc.x # oldDoc.x THEN
(* evtl. horizontales scrollen *)
IF (doc.x > oldDoc.x) & ~fullRedraw THEN
(* Nach links scrollen *)
IF (doc.x - oldDoc.x) * xFactor < LONG(wdwWork.w)
THEN
(* Scrollen lohnt sich *)
scrollLR (wdwPtr, RIGHT, SHORT((doc.x - oldDoc.x)*xFactor));
ELSE
fullRedraw := TRUE;
END;
ELSIF ~fullRedraw
THEN
IF (oldDoc.x - doc.x) * xFactor < LONG(wdwWork.w)
THEN
(* Scrollen lohnt sich *)
scrollLR (wdwPtr, LEFT, SHORT((oldDoc.x - doc.x)*xFactor));
ELSE
fullRedraw := TRUE;
END;
END;
END;
IF doc.y # oldDoc.y THEN
(* evtl. vertikales scrollen *)
IF ~fullRedraw & (doc.y > oldDoc.y) THEN
(* Nach oben scrollen *)
IF (doc.y - oldDoc.y) * yFactor < LONG(wdwWork.h)
THEN
(* Scrollen lohnt sich *)
scrollWdw (wdwPtr, DOWN, SHORT((doc.y - oldDoc.y)*yFactor));
ELSE
fullRedraw := TRUE;
END;
ELSIF ~fullRedraw
THEN
IF (oldDoc.y - doc.y) * yFactor < LONG(wdwWork.h)
THEN
(* Scrollen lohnt sich *)
scrollWdw (wdwPtr, UP, SHORT((oldDoc.y - doc.y)*yFactor));
ELSE
fullRedraw := TRUE;
END;
END;
END;
IF fullRedraw
THEN
updateWdw (wdwPtr, wdwWork);
END;
IF (doc.y # oldDoc.y) OR (doc.h # oldDoc.h)
THEN
CalcVSlider (wdwPtr);
END;
IF (doc.x # oldDoc.x) OR (doc.w # oldDoc.w)
THEN
CalcHSlider (wdwPtr);
END;
END;
END;
END SetWdwDocument;
PROCEDURE GetWdwDocument (wdw : INTEGER; VAR doc : LongRect);
(* Erfragt die aktuellen Dokument-Parameter
*)
VAR wdwPtr : ptrWdwSlot;
BEGIN
wdwPtr := FindWindow (wdw);
IF wdwPtr # NIL
THEN
doc := wdwPtr^.document;
END;
END GetWdwDocument;
PROCEDURE RedrawWdw (wdw : INTEGER; frame : Rectangle);
(* Zeichnet das Fenster im Bereich Frame neu, beachtet
* Rechteckliste und ruft indirekt die drawProc auf
*)
VAR wdwPtr : ptrWdwSlot;
BEGIN
wdwPtr := FindWindow (wdw);
IF wdwPtr # NIL
THEN
updateWdw (wdwPtr, frame);
END;
END RedrawWdw;
PROCEDURE FullRedrawWdw (wdw : INTEGER);
(* Zeichnet das Fenster im Bereich Frame neu, beachtet
* Rechteckliste und ruft indirekt die drawProc auf
*)
VAR wdwPtr : ptrWdwSlot;
r : Rectangle;
BEGIN
wdwPtr := FindWindow (wdw);
IF wdwPtr # NIL
THEN
MagicAES.WindGet (wdw, MagicAES.WFWORKXYWH, r);
updateWdw (wdwPtr, r);
END;
END FullRedrawWdw;
PROCEDURE SetWdwInfoline (wdw : INTEGER; info : ARRAY OF CHAR);
VAR wdwPtr : ptrWdwSlot;
adr : RECORD a,b : ADDRESS END;
voidO : BOOLEAN;
BEGIN
wdwPtr := FindWindow (wdw);
IF wdwPtr # NIL
THEN
WITH wdwPtr^ DO
Strings.Assign (info, wdwInfo, voidO);
IF MagicAES.INFO IN comps
THEN
(* Infozeile *)
adr.a := ADR(wdwInfo);
MagicAES.WindSet(wdw, MagicAES.WFINFO, adr);
END;
END;
END;
END SetWdwInfoline;
PROCEDURE SetWdwTitle (wdw : INTEGER; title : ARRAY OF CHAR);
VAR wdwPtr : ptrWdwSlot;
adr : RECORD a,b : ADDRESS END;
voidO : BOOLEAN;
BEGIN
wdwPtr := FindWindow (wdw);
IF wdwPtr # NIL
THEN
WITH wdwPtr^ DO
Strings.Assign (title, wdwTitle, voidO);
IF LENGTH (wdwTitle) > 0
THEN
(* Jetzt ggf. ein Space vorne und hinten anfgen *)
IF wdwTitle[0] # ' '
THEN
Strings.Insert (' ', 0, wdwTitle, voidO);
END;
IF wdwTitle[LENGTH(wdwTitle)-1] # ' '
THEN
Strings.Append (' ', wdwTitle, voidO);
END;
END;
IF MagicAES.NAME IN comps
THEN
(* Titelzeile *)
adr.a := ADR(wdwTitle);
MagicAES.WindSet(wdw, MagicAES.WFNAME, adr);
END;
END;
END;
END SetWdwTitle;
PROCEDURE OpenWindow (button : handleButtonProc; key : handleKeyProc; timer : handleTimerProc;
fullSize : Rectangle; VAR currSize : Rectangle; wdwParts : BITSET;
wdwSnap : BOOLEAN; REF info, titel : ARRAY OF CHAR;
snapP : snapProc; close : closeProc; draw : drawProc; top : topProc;
untop : untopProc; update : updateProc; setWdw : setWorkProc;
getScroll : getRectProc; hide : hideProc;
pixelOffset : INTEGER; env : ADDRESS;
onlyThisTop : BOOLEAN; showIt : BOOLEAN;
supportIconify : BOOLEAN; openWorkstation: BOOLEAN;
VAR wdwHandle, vdiHandle : INTEGER): BOOLEAN;
(* ffnet Fenster und Workstation, setzt Font und Size,
* alle Prozeduren setzen
*)
VAR wdwPtr : ptrWdwSlot;
work : Rectangle;
adr : RECORD a,b : ADDRESS END;
oldTop : ptrWdwSlot;
bits : INTEGER;
voidO : BOOLEAN;
BEGIN
(*
IF onlyThisTop & (onlyOneTop >= 0)
THEN
wdwHandle := -1;
vdiHandle := -1;
RETURN FALSE
END;
*)
(* Neuen WindowPtr einrichten, Window erzeugen und ffnen, Workstation ffnen *)
NEW (wdwPtr);
IF wdwPtr = NIL
THEN
RETURN FALSE
END;
IF iconifySupportEnabled & supportIconify
THEN
IF (MagicAES.ApplGetinfo (MagicAES.AEWINDOWS, v.int, v.int, bits, v.int) = 1)
THEN
IF MagicSys.Bit0 IN BITSET(bits)
THEN
(* Iconify-Gadget einfgen *)
INCL (wdwParts, MagicAES.SMALLER);
END;
(*
IF MagicSys.Bit3 IN BITSET(bits)
THEN
(* HotClose-Box einfgen (wasauchimmer das sein mag) *)
INCL (wdwParts, MagicAES.HOTCLOSEBOX);
END;
*)
END;
END;
IF magIx
THEN
IF (MagicAES.NAME IN wdwParts) OR (MagicAES.MOVE IN wdwParts)
THEN
(* Backdrop hinzufgen, damit wir die Message bekommen! *)
INCL (wdwParts, MagicAES.BACKDROP);
END;
END;
wdwHandle := MagicAES.WindCreate (wdwParts, fullSize);
IF wdwHandle < 0
THEN
(* Kein Fenster mehr frei *)
DISPOSE (wdwPtr);
RETURN FALSE;
END;
IF openWorkstation
THEN
vdiHandle := mtAppl.OpenWorkstation (mtAppl.Screen, 0, 0, TRUE);
IF vdiHandle < 0 THEN
DISPOSE (wdwPtr);
MagicAES.WindDelete (wdwHandle);
RETURN FALSE
END;
ELSE
vdiHandle := -1
END;
(* So, jetzt noch in Liste einhngen *)
wdwPtr^.prev := NIL;
IF windows = NIL
THEN
wdwPtr^.next := NIL;
ELSE
(* Am Anfang einhngen *)
wdwPtr^.next := windows;
windows^.prev := wdwPtr;
END;
windows := wdwPtr;
(* Ok, alles da! *)
WITH wdwPtr^ DO
wdw := wdwHandle;
vdi := vdiHandle;
used := TRUE;
isTop := TRUE;
isFull := FALSE;
comps := wdwParts;
snap := wdwSnap;
wdwFull := fullSize;
pixOff := pixelOffset;
wdwMenu := NIL;
wdwDial := NIL;
onlyTop := onlyThisTop;
lastOnlyTop := onlyOneTop;
IF onlyThisTop
THEN
onlyOneTop := wdwHandle;
END;
(* Event-Handler installieren *)
hdlButton := button;
hdlKey := key;
hdlTimer := timer;
(* Slidergren initialisieren *)
VslSize := -1;
VslPos := -1;
HslSize := -1;
HslPos := -1;
(* Request-Handler installieren *)
hdlSnap := snapP;
hdlClose := close;
hdlDraw := draw;
hdlTop := top;
hdlUntop := untop;
hdlUpdate := update;
setNewWdw := setWdw;
wdwGetScroll := getScroll;
hdlHide := hide;
hdlRect := handleRectProc(NIL);
special := env;
ddClientInstalled := FALSE;
ddServerInstalled := FALSE;
WITH currSize DO
w := BinOps.HigherInt (w, minWindWidth);
h := BinOps.HigherInt (h, minWindHeight);
END;
wdwCurr := currSize;
(* Dokument-Variablen setzen *)
document := LongRect {0, 0, 0, 0};
pageW := 0;
pageH := 0;
yFactor := 1;
xFactor := 1;
minScrollW := 1;
minScrollH := 1;
(* Titel und Infozeile setzen *)
Strings.Assign (titel, wdwTitle, v.bool);
Strings.Assign (info, wdwInfo, v.bool);
IF MagicAES.INFO IN comps
THEN
(* Infozeile *)
adr.a := ADR(wdwInfo);
MagicAES.WindSet(wdw, MagicAES.WFINFO, adr);
END;
IF MagicAES.NAME IN comps
THEN
(* Jetzt ggf. ein Space vorne und hinten anfgen *)
IF LENGTH (wdwTitle) > 0
THEN
IF wdwTitle[0] # ' '
THEN
Strings.Insert (' ', 0, wdwTitle, voidO);
END;
IF wdwTitle[LENGTH(wdwTitle)-1] # ' '
THEN
Strings.Append (' ', wdwTitle, voidO);
END;
END;
(* Titelzeile *)
adr.a := ADR(wdwTitle);
MagicAES.WindSet(wdw, MagicAES.WFNAME, adr);
END;
(* Jetzt Fenster ffnen *)
MagicAES.WindCalc (MagicAES.WCWORK, comps, currSize, wdwWork);
(* Jetzt snappen *)
IF snap THEN hdlSnap (wdw, vdi, special, wdwWork); END;
(* Scrollrechteck holen *)
MagicAES.WindCalc (MagicAES.WCBORDER, comps, wdwWork, wdwCurr);
wdwGetScroll (wdw, vdi, special, wdwWork);
IF showIt THEN
(* Altes TopWindow untoppen *)
oldTop := FindTop();
IF oldTop # NIL THEN
untopWdw (oldTop);
END;
MagicAES.WindOpen (wdw, wdwCurr);
v.bool := hdlTop (wdw, vdi, special);
END;
isHidden := ~showIt;
isIcon := FALSE;
END; (* WITH wdwPtr *)
IF showIt
THEN
(* Noch merken, das dieses jetzt top ist *)
NewWindowIsTop (wdwHandle, mtAppl.ApplIdent);
END;
(* fettisch! *)
RETURN TRUE
END OpenWindow;
PROCEDURE CreateWindow (fullSize : Rectangle; VAR currSize : Rectangle;
wdwParts : BITSET; REF info, titel : ARRAY OF CHAR;
env : ADDRESS; supportIconify: BOOLEAN;
openWorkstation: BOOLEAN;
VAR wdwHandle, vdiHandle : INTEGER): BOOLEAN;
(* Erzeugt ein Fenster, das mit Default-Prozeduren behandelt wird.
* Weitere Einstellungen mu man danach vornehmen
*)
VAR wdwPtr : ptrWdwSlot;
work : Rectangle;
adr : RECORD a,b : ADDRESS END;
oldTop : ptrWdwSlot;
bits : INTEGER;
voidO : BOOLEAN;
BEGIN
(* Neuen WindowPtr einrichten, Window erzeugen und ffnen, Workstation ffnen *)
NEW (wdwPtr);
IF wdwPtr = NIL
THEN
RETURN FALSE
END;
IF iconifySupportEnabled & supportIconify
THEN
IF (MagicAES.ApplGetinfo (MagicAES.AEWINDOWS, v.int, v.int, bits, v.int) = 1)
& (MagicSys.Bit0 IN BITSET(bits))
THEN
(* Iconify-Gadget einfgen *)
INCL (wdwParts, MagicAES.SMALLER);
END;
END;
wdwHandle := MagicAES.WindCreate (wdwParts, fullSize);
IF wdwHandle < 0
THEN
(* Kein Fenster mehr frei *)
DISPOSE (wdwPtr);
RETURN FALSE;
END;
IF openWorkstation
THEN
vdiHandle := mtAppl.OpenWorkstation (mtAppl.Screen, 0, 0, TRUE);
IF vdiHandle < 0 THEN
DISPOSE (wdwPtr);
MagicAES.WindDelete (wdwHandle);
RETURN FALSE
END;
ELSE
vdiHandle := -1
END;
(* So, jetzt noch in Liste einhngen *)
wdwPtr^.prev := NIL;
IF windows = NIL
THEN
wdwPtr^.next := NIL;
ELSE
(* Am Anfang einhngen *)
wdwPtr^.next := windows;
windows^.prev := wdwPtr;
END;
windows := wdwPtr;
(* Ok, alles da! *)
WITH wdwPtr^ DO
wdw := wdwHandle;
vdi := vdiHandle;
used := TRUE;
isTop := FALSE;
isFull := FALSE;
comps := wdwParts;
snap := FALSE;
wdwFull := fullSize;
pixOff := 0;
wdwMenu := NIL;
wdwDial := NIL;
onlyTop := FALSE;
(* Default Event-Handler installieren *)
hdlButton := defButton;
hdlKey := defKey;
hdlTimer := defTimer;
(* Slidergren initialisieren *)
VslSize := -1;
VslPos := -1;
HslSize := -1;
HslPos := -1;
(* Default Request-Handler installieren *)
hdlSnap := defSnap;
hdlClose := defClose;
hdlDraw := defDraw;
hdlTop := defTop;
hdlUntop := defUntop;
hdlUpdate := defUpdate;
setNewWdw := defSetwork;
wdwGetScroll := defGetrect;
hdlHide := defHide;
hdlRect := handleRectProc(NIL);
special := env;
ddClientInstalled := FALSE;
ddServerInstalled := FALSE;
WITH currSize DO
w := BinOps.HigherInt (w, minWindWidth);
h := BinOps.HigherInt (h, minWindHeight);
END;
wdwCurr := currSize;
(* Dokument-Variablen setzen *)
document := LongRect {0, 0, 0, 0};
pageW := 0;
pageH := 0;
yFactor := 1;
xFactor := 1;
minScrollW := 1;
minScrollH := 1;
(* Titel und Infozeile setzen *)
Strings.Assign (titel, wdwTitle, v.bool);
Strings.Assign (info, wdwInfo, v.bool);
IF MagicAES.INFO IN comps
THEN
(* Infozeile *)
adr.a := ADR(wdwInfo);
MagicAES.WindSet(wdw, MagicAES.WFINFO, adr);
END;
IF MagicAES.NAME IN comps
THEN
(* Jetzt ggf. ein Space vorne und hinten anfgen *)
IF LENGTH (wdwTitle) > 0
THEN
IF wdwTitle[0] # ' '
THEN
Strings.Insert (' ', 0, wdwTitle, voidO);
END;
IF wdwTitle[LENGTH(wdwTitle)-1] # ' '
THEN
Strings.Append (' ', wdwTitle, voidO);
END;
END;
(* Titelzeile *)
adr.a := ADR(wdwTitle);
MagicAES.WindSet(wdw, MagicAES.WFNAME, adr);
END;
(* Jetzt Fenster ffnen *)
MagicAES.WindCalc (MagicAES.WCWORK, comps, currSize, wdwWork);
(* Jetzt snappen *)
IF snap THEN hdlSnap (wdw, vdi, special, wdwWork); END;
(* Scrollrechteck holen *)
MagicAES.WindCalc (MagicAES.WCBORDER, comps, wdwWork, wdwCurr);
wdwGetScroll (wdw, vdi, special, wdwWork);
isHidden := TRUE;
isIcon := FALSE;
END; (* WITH wdwPtr *)
(* fettisch! *)
RETURN TRUE
END CreateWindow;
PROCEDURE SetWindowDraw (wdw: INTEGER; draw: drawProc): BOOLEAN;
(* Setzt die Zeichenprozedur fr ein Fenster. False: Fenster nicht gefunden
*)
VAR wdwPtr : ptrWdwSlot;
BEGIN
wdwPtr := FindWindow (wdw);
IF (wdwPtr # NIL)
THEN
wdwPtr^.hdlDraw := draw;
END;
RETURN wdwPtr # NIL
END SetWindowDraw;
PROCEDURE SetWindowSnap (wdw: INTEGER; snap: snapProc): BOOLEAN;
(* Setzt die Snapprozedur fr ein Fenster. Diese wird dann
* bei jedem Sizen und einmal direkt mit den aktuellen Werten
* aufgerufen. False: Fenster nicht gefunden
*)
VAR wdwPtr : ptrWdwSlot;
BEGIN
wdwPtr := FindWindow (wdw);
IF (wdwPtr # NIL)
THEN
wdwPtr^.hdlSnap := snap;
wdwPtr^.snap := TRUE;
END;
RETURN wdwPtr # NIL
END SetWindowSnap;
PROCEDURE SetWindowButton (wdw: INTEGER; button: handleButtonProc): BOOLEAN;
(* Setzt den Buttonhandler fr ein Fenster. False: Fenster nicht gefunden
*)
VAR wdwPtr : ptrWdwSlot;
BEGIN
wdwPtr := FindWindow (wdw);
IF (wdwPtr # NIL)
THEN
wdwPtr^.hdlButton := button;
END;
RETURN wdwPtr # NIL
END SetWindowButton;
PROCEDURE SetWindowKey (wdw: INTEGER; key: handleKeyProc): BOOLEAN;
(* Setzt den Keyhandler fr ein Fenster. False: Fenster nicht gefunden
*)
VAR wdwPtr : ptrWdwSlot;
BEGIN
wdwPtr := FindWindow (wdw);
IF (wdwPtr # NIL)
THEN
wdwPtr^.hdlKey := key;
END;
RETURN wdwPtr # NIL
END SetWindowKey;
PROCEDURE SetWindowTimer (wdw: INTEGER; timer: handleTimerProc): BOOLEAN;
(* Setzt den Timerhandler fr ein Fenster. False: Fenster nicht gefunden
*)
VAR wdwPtr : ptrWdwSlot;
BEGIN
wdwPtr := FindWindow (wdw);
IF (wdwPtr # NIL)
THEN
wdwPtr^.hdlTimer := timer;
END;
RETURN wdwPtr # NIL
END SetWindowTimer;
PROCEDURE SetWindowRectProc (wdw: INTEGER; rect: handleRectProc): BOOLEAN;
(* Setzt den Rechteckhandler fr ein Fenster. False: Fenster nicht gefunden
*)
VAR wdwPtr : ptrWdwSlot;
BEGIN
wdwPtr := FindWindow (wdw);
IF (wdwPtr # NIL)
THEN
wdwPtr^.hdlRect := rect;
END;
RETURN wdwPtr # NIL
END SetWindowRectProc;
PROCEDURE SetWindowClose (wdw: INTEGER; close: closeProc): BOOLEAN;
(* Setzt den Closehandler fr ein Fenster. False: Fenster nicht gefunden
*)
VAR wdwPtr : ptrWdwSlot;
BEGIN
wdwPtr := FindWindow (wdw);
IF (wdwPtr # NIL)
THEN
wdwPtr^.hdlClose := close;
END;
RETURN wdwPtr # NIL
END SetWindowClose;
PROCEDURE SetWindowTop (wdw: INTEGER; top: topProc): BOOLEAN;
(* Setzt den Tophandler fr ein Fenster. False: Fenster nicht gefunden
*)
VAR wdwPtr : ptrWdwSlot;
BEGIN
wdwPtr := FindWindow (wdw);
IF (wdwPtr # NIL)
THEN
wdwPtr^.hdlTop := top;
END;
RETURN wdwPtr # NIL
END SetWindowTop;
PROCEDURE SetWindowUntop (wdw: INTEGER; untop: untopProc): BOOLEAN;
(* Setzt den Untophandler fr ein Fenster. False: Fenster nicht gefunden
*)
VAR wdwPtr : ptrWdwSlot;
BEGIN
wdwPtr := FindWindow (wdw);
IF (wdwPtr # NIL)
THEN
wdwPtr^.hdlUntop := untop;
END;
RETURN wdwPtr # NIL
END SetWindowUntop;
PROCEDURE SetWindowUpdate (wdw: INTEGER; update: updateProc): BOOLEAN;
(* Setzt den Updatehandler fr ein Fenster. False: Fenster nicht gefunden
*)
VAR wdwPtr : ptrWdwSlot;
BEGIN
wdwPtr := FindWindow (wdw);
IF (wdwPtr # NIL)
THEN
wdwPtr^.hdlUpdate := update;
END;
RETURN wdwPtr # NIL
END SetWindowUpdate;
PROCEDURE SetWindowSwork (wdw: INTEGER; setWdw: setWorkProc): BOOLEAN;
(* Setzt den Handler fr Dokumentnderungen im Fenster. False: Fenster nicht gefunden
*)
VAR wdwPtr : ptrWdwSlot;
BEGIN
wdwPtr := FindWindow (wdw);
IF (wdwPtr # NIL)
THEN
wdwPtr^.setNewWdw := setWdw;
END;
RETURN wdwPtr # NIL
END SetWindowSwork;
PROCEDURE SetWindowGetScroll (wdw: INTEGER; getScroll: getRectProc): BOOLEAN;
(* Setzt den GetScrollRect-Handler fr ein Fenster. False: Fenster nicht gefunden
*)
VAR wdwPtr : ptrWdwSlot;
BEGIN
wdwPtr := FindWindow (wdw);
IF (wdwPtr # NIL)
THEN
wdwPtr^.wdwGetScroll := getScroll;
END;
RETURN wdwPtr # NIL
END SetWindowGetScroll;
PROCEDURE SetWindowHide (wdw: INTEGER; hide: hideProc): BOOLEAN;
(* Setzt den Hidehandler fr ein Fenster. False: Fenster nicht gefunden
*)
VAR wdwPtr : ptrWdwSlot;
BEGIN
wdwPtr := FindWindow (wdw);
IF (wdwPtr # NIL)
THEN
wdwPtr^.hdlHide := hide;
END;
RETURN wdwPtr # NIL
END SetWindowHide;
PROCEDURE SetWindowPixOff (wdw: INTEGER; pixelOffset: INTEGER): BOOLEAN;
(* Setzt den linken Offset fr ein Fenster. False: Fenster nicht gefunden
*)
VAR wdwPtr : ptrWdwSlot;
BEGIN
wdwPtr := FindWindow (wdw);
IF (wdwPtr # NIL)
THEN
wdwPtr^.pixOff := pixelOffset;
END;
RETURN wdwPtr # NIL
END SetWindowPixOff;
PROCEDURE SetWindowMode (wdw: INTEGER; onlyThisTop: BOOLEAN): BOOLEAN;
(* Setzt den Modus fr ein Fenster. False: Fenster nicht gefunden
*)
VAR wdwPtr : ptrWdwSlot;
BEGIN
(*
IF onlyThisTop & (onlyOneTop >= 0)
THEN
RETURN FALSE
END;
*)
wdwPtr := FindWindow (wdw);
IF (wdwPtr # NIL)
THEN
wdwPtr^.onlyTop := onlyThisTop;
IF onlyThisTop
THEN
wdwPtr^.lastOnlyTop := onlyOneTop;
onlyOneTop := wdw;
END;
END;
RETURN wdwPtr # NIL
END SetWindowMode;
PROCEDURE SetWindowDial (wdw: INTEGER; dial: ADDRESS): BOOLEAN;
(* Setzt die Dialogadresse fr das Fenster. False: Fenster nicht gefunden
*)
VAR wdwPtr : ptrWdwSlot;
BEGIN
wdwPtr := FindWindow (wdw);
IF (wdwPtr # NIL)
THEN
wdwPtr^.wdwDial := dial;
END;
RETURN wdwPtr # NIL
END SetWindowDial;
PROCEDURE SetWindowMenu (wdw: INTEGER; menu: ADDRESS): BOOLEAN;
(* Setzt die Menuadresse fr das Fenster. False: Fenster nicht gefunden
*)
VAR wdwPtr : ptrWdwSlot;
BEGIN
wdwPtr := FindWindow (wdw);
IF (wdwPtr # NIL)
THEN
wdwPtr^.wdwMenu := menu;
END;
RETURN wdwPtr # NIL
END SetWindowMenu;
PROCEDURE ShowWindow (wdw: INTEGER) : BOOLEAN;
VAR wdwPtr : ptrWdwSlot;
BEGIN
wdwPtr := FindWindow (wdw);
IF (wdwPtr # NIL) & (wdwPtr^.isHidden)
THEN
showWdw (wdwPtr, TRUE);
RETURN TRUE;
ELSE
RETURN FALSE
END;
END ShowWindow;
PROCEDURE HideWindow (wdw: INTEGER) : BOOLEAN;
VAR wdwPtr : ptrWdwSlot;
BEGIN
wdwPtr := FindWindow (wdw);
IF (wdwPtr # NIL) & ~(wdwPtr^.isHidden)
THEN
hideWdw (wdwPtr);
RETURN TRUE;
ELSE
RETURN FALSE
END;
END HideWindow;
PROCEDURE SendCloseWindow (wdw : INTEGER);
VAR wdwPtr : ptrWdwSlot;
apId : INTEGER;
BEGIN
wdwPtr := FindWindow (wdw);
IF wdwPtr # NIL
THEN
apId := mtAppl.ApplIdent;
SendClosed (wdw, apId);
ELSE
IF GetApId (wdw, apId)
THEN
SendClosed (wdw, apId);
END;
END;
END SendCloseWindow;
PROCEDURE CloseWindow (wdw : INTEGER; force : BOOLEAN): BOOLEAN;
(* Schliet Fenster und Workstation und entfernt die Handler aus der Liste
*)
VAR wdwPtr : ptrWdwSlot;
apId : INTEGER;
BEGIN
wdwPtr := FindWindow (wdw);
IF wdwPtr # NIL
THEN
IF (onlyOneTop >= 0) & (wdwPtr^.wdw # onlyOneTop) & (~force) THEN
RETURN FALSE
END;
RETURN closeWdw (wdwPtr, force);
ELSE
IF GetApId (wdw, apId)
THEN
SendClosed (wdw, apId);
END;
END;
RETURN TRUE
END CloseWindow;
PROCEDURE CloseAllWindows (force : BOOLEAN): BOOLEAN;
(* Schliet alle Fenster, die dem Modul bekannt sind.
* Die Fenster werden alle ber CloseWindow geschlossen,
* und falls ein CloseWindow FALSE zurckliefert, dann
* wird der Returnwert zurckgegeben und abgebrochen.
*)
VAR wdwPtr : ptrWdwSlot;
BEGIN
wdwPtr := windows;
WHILE wdwPtr # NIL DO
IF ~ CloseWindow (wdwPtr^.wdw, force)
THEN
RETURN FALSE
END;
wdwPtr := windows;
END;
RETURN TRUE;
END CloseAllWindows;
PROCEDURE FullWindow (wdw : INTEGER);
(* Tut so, als ob das Fenster eine Fulled-Nachricht erhalten htte.
* Falls das Fenster nicht vom Modul verwaltet wird, aber trotzdem
* in der WindowQueue enthalten ist, dann wird an das Fenster
* eine Fulled-Nachricht geschickt.
*)
VAR wdwPtr : ptrWdwSlot;
apId : INTEGER;
BEGIN
wdwPtr := FindWindow (wdw);
IF wdwPtr # NIL
THEN
fullWdw (wdwPtr);
ELSE
IF GetApId (wdw, apId)
THEN
SendFulled (wdw, apId);
END;
END;
END FullWindow;
PROCEDURE TopWindow (wdw : INTEGER);
(* Tut so, als ob das Fenster eine Topped-Nachricht erhalten htte.
* Falls das Fenster nicht vom Modul verwaltet wird, aber trotzdem
* in der WindowQueue enthalten ist, dann wird an das Fenster
* eine Topped-Nachricht geschickt.
*)
VAR wdwPtr : ptrWdwSlot;
apId : INTEGER;
BEGIN
wdwPtr := FindWindow (wdw);
IF wdwPtr # NIL
THEN
topWdw (wdwPtr, TRUE);
ELSE
IF GetApId (wdw, apId)
THEN
SendTop (wdw, apId);
END;
END;
END TopWindow;
PROCEDURE SetWindowIcon (icon : ADDRESS);
(* Setzt das Icon, das in iconifizierten Fenstern gezeichnet wird.
* icon ist die Adresse eines Objektbaumes
*)
BEGIN
iconHdl := icon;
END SetWindowIcon;
PROCEDURE TranslateKey (VAR key, scan: CHAR; taste: INTEGER; kstate: BITSET);
BEGIN
IF MagicPCKeyTrans
THEN
CASE taste OF
$6328: (* PageUp auf PC, umgesetzt auf Num-( *)
taste := $4838;
scan := CHAR($48); key := CHAR($38);
kstate := BITSET(2);
| $6429: (* PageDown auf PC, umgesetzt auf Num-) *)
taste := $5032;
scan := CHAR($50); key := CHAR($32);
kstate := BITSET(2);
| $4F00: (* End auf Mac *)
taste := $4737;
scan := CHAR($47); key := CHAR($37);
kstate := BITSET(2);
ELSE
END;
ELSE
CASE taste OF
$4900: (* PageUp auf Mac *)
taste := $4838;
scan := CHAR($48); key := CHAR($38);
kstate := BITSET(2);
| $5100: (* PageDown auf Mac *)
taste := $5032;
scan := CHAR($50); key := CHAR($32);
kstate := BITSET(2);
| $4F00: (* End auf Mac *)
taste := $4737;
scan := CHAR($47); key := CHAR($37);
kstate := BITSET(2);
ELSE
END;
END;
END TranslateKey;
PROCEDURE HandleEvent ( VAR event : BITSET; VAR pbuff : ARRAY OF LOC; buts, kstate : BITSET;
key, scan : CHAR; taste, mx, my, clicks : INTEGER) : BOOLEAN;
(* Verteilt die events, falls ntig. Wenn behandelt, wird TRUE zurckgegeben,
* andernfalls FALSE
*)
VAR wdwPtr : ptrWdwSlot;
r : Rectangle;
eventDone : BOOLEAN;
evtDone: BOOLEAN;
BEGIN
eventDone := FALSE;
MagicAES.WindGet (0, MagicAES.WFTOP, r);
theTopWindow := r.x;
GetOwnTopWindow (ownTopWindow);
IF (theTopWindow # ownTopWindow) & (FindWindow (theTopWindow) # NIL)
THEN
NewWindowIsTop (theTopWindow, mtAppl.ApplIdent);
ownTopWindow := theTopWindow;
END;
(* Tastendrcke, gehen an Dialog oder an Fenster, wenn mit Shift *)
IF MagicAES.MUKEYBD IN event
THEN
TranslateKey (key, scan, taste, kstate);
wdwPtr := FindWindow (ownTopWindow);
IF wdwPtr # NIL
THEN
IF (onlyOneTop >= 0) OR
(wdwPtr^.wdwDial # NIL) OR
(MagicAES.KLSHIFT IN kstate) OR (MagicAES.KRSHIFT IN kstate)
THEN
WITH wdwPtr^ DO
IF ~isIcon & ~isHidden & (hdlKey # handleKeyProc(NIL)) & hdlKey (wdw, vdi, special, taste, key, scan, kstate)
THEN
EXCL (event, MagicAES.MUKEYBD);
eventDone := TRUE;
END;
END;
END
END;
END;
(* Jetzt Tastendrcke ohne Shift, gehen an globale Prozedur *)
IF (MagicAES.MUKEYBD IN event) (* nicht vom Fenster behandelt *)
& (handleGlobalKey # handleGlobalKeyProc (NIL))
THEN
IF handleGlobalKey ( taste, key, scan, kstate)
THEN
EXCL (event, MagicAES.MUKEYBD);
eventDone := TRUE;
END;
END;
(* Jetzt Tastendrcke ohne Shift, die noch brig sind *)
IF MagicAES.MUKEYBD IN event
THEN
wdwPtr := FindWindow (ownTopWindow);
IF wdwPtr # NIL
THEN WITH wdwPtr^ DO
IF ~isIcon & ~isHidden & (hdlKey # handleKeyProc(NIL)) & hdlKey (wdw, vdi, special, taste, key, scan, kstate)
THEN
EXCL (event, MagicAES.MUKEYBD);
eventDone := TRUE;
END;
END END;
END;
(* Jetzt Rechteckevents *)
IF MagicAES.MUM1 IN event
THEN
wdwPtr := FindWindow (ownTopWindow);
IF wdwPtr # NIL
THEN WITH wdwPtr^ DO
IF ~isIcon & ~isHidden & (hdlRect # handleRectProc(NIL)) &
hdlRect (wdw, vdi, special, 1, mx, my)
THEN
EXCL (event, MagicAES.MUM1);
eventDone := TRUE;
END;
END END;
END;
IF MagicAES.MUM2 IN event
THEN
wdwPtr := FindWindow (ownTopWindow);
IF wdwPtr # NIL
THEN WITH wdwPtr^ DO
IF ~isIcon & ~isHidden & (hdlRect # handleRectProc(NIL)) &
hdlRect (wdw, vdi, special, 2, mx, my)
THEN
EXCL (event, MagicAES.MUM2);
eventDone := TRUE;
END;
END END;
END;
IF MagicAES.MUMESAG IN event THEN
evtDone := MessageEvent (ADR(pbuff));
IF evtDone THEN
EXCL (event, MagicAES.MUMESAG);
ELSIF (handleGlobalMess # handleMessProc (NIL))
THEN
(* Wenn noch nicht behandelt, dann gehen die an den globalen
* Handler, falls installiert
*)
evtDone := handleGlobalMess (ADR(pbuff), kstate);
IF evtDone THEN
EXCL (event, MagicAES.MUMESAG);
END;
END;
eventDone := eventDone OR evtDone;
END;
IF MagicAES.MUBUTTON IN event
THEN
r.x := MagicAES.WindFind (mx, my);
wdwPtr := FindWindow (r.x);
IF wdwPtr # NIL
THEN WITH wdwPtr^ DO
IF ~isIcon & ~isHidden & (hdlButton # handleButtonProc (NIL)) & hdlButton (wdw, vdi, special, mx, my, kstate, buts, clicks)
THEN
EXCL (event, MagicAES.MUBUTTON);
eventDone := TRUE;
END;
END END;
END;
IF MagicAES.MUTIMER IN event
THEN
wdwPtr := windows;
WHILE wdwPtr # NIL DO
WITH wdwPtr^ DO
IF ~isIcon & ~isHidden
THEN
eventDone := eventDone OR ((hdlTimer # handleTimerProc(NIL)) & hdlTimer (wdw, vdi, special));
END;
END;
wdwPtr := wdwPtr^.next;
END;
END;
IF handlePostEvent # handleEventProc(NIL)
THEN
handlePostEvent (theTopWindow);
END;
RETURN eventDone
END HandleEvent;
PROCEDURE HandlePendingEvents();
VAR etv : BITSET;
event : BITSET;
mess : ARRAY [0..7] OF INTEGER;
key,
scan : CHAR;
buts,
kstate: BITSET;
iScan,
taste,
mx,
my,
clicks: INTEGER;
BEGIN
REPEAT
event := MagicAES.EvntMulti(
{MagicAES.MUMESAG, MagicAES.MUTIMER},
0, {},{}, 0, v.r, 0, v.r, mess, 50, 0,
mx, my, buts, taste, kstate, iScan, key, clicks);
etv := event;
IF MagicAES.MUMESAG IN event
THEN
MagicAES.WindUpdate(MagicAES.BEGUPDATE);
scan := CHR(iScan);
v.bool := HandleEvent (event, mess, buts, kstate, key, scan, taste, mx, my, clicks);
MagicAES.WindUpdate(MagicAES.ENDUPDATE);
END;
UNTIL ~(MagicAES.MUMESAG IN etv);
END HandlePendingEvents;
PROCEDURE GetTopWindow (VAR wdw, handle : INTEGER);
VAR r : Rectangle;
wdwPtr : ptrWdwSlot;
BEGIN
MagicAES.WindGet (0, MagicAES.WFTOP, r);
wdw := r.x;
theTopWindow := wdw;
wdwPtr := FindWindow (wdw);
IF wdwPtr # NIL
THEN
handle := wdwPtr^.vdi;
wdwPtr^.isTop := TRUE;
ELSE
handle := -1
END;
END GetTopWindow;
PROCEDURE IsOwnTop (): BOOLEAN;
(* Liefert zurck, ob ein eigenes Fenster, das vom Windowmanager verwaltet
* wird, das Topwindow ist
*)
VAR r : Rectangle;
wdwPtr : ptrWdwSlot;
BEGIN
MagicAES.WindGet (0, MagicAES.WFTOP, r);
theTopWindow := r.x;
wdwPtr := FindWindow (theTopWindow);
RETURN wdwPtr # NIL;
END IsOwnTop;
PROCEDURE WindowIsIcon (wdw: INTEGER) : BOOLEAN;
(* Liefert TRUE, wenn das Window vorhanden und iconifiziert ist
*)
VAR wdwPtr : ptrWdwSlot;
BEGIN
wdwPtr := FindWindow (wdw);
IF wdwPtr # NIL
THEN
RETURN wdwPtr^.isIcon
END;
RETURN FALSE
END WindowIsIcon;
PROCEDURE ModalWindowTop (): BOOLEAN;
(* Liefert TRUE, wenn das Topwindow ein eigenes und modal ist
*)
BEGIN
RETURN IsOwnTop() & (onlyOneTop >= 0) & (onlyOneTop = theTopWindow);
END ModalWindowTop;
PROCEDURE WindowIsShaded (wdw: INTEGER) : BOOLEAN;
(* Liefert TRUE, wenn das Window vorhanden und mittels WindowShade
* geshadet ist (oder auerhalb des Bildschirms liegt)
*)
VAR wdwPtr : ptrWdwSlot;
isShaded: BOOLEAN;
work : Rectangle;
BEGIN
wdwPtr := FindWindow (wdw);
IF wdwPtr # NIL
THEN
isShaded := ~RectList (wdw, 0, work);
IF ~isShaded
THEN
(* Rechteckliste bis zum Ende abklappern
*)
REPEAT UNTIL ~RectList (wdw, 1, work);
END;
RETURN isShaded;
END;
RETURN FALSE
END WindowIsShaded;
PROCEDURE WindowIsCloseable (wdw: INTEGER) : BOOLEAN;
(* Liefert TRUE, wenn das Window vorhanden und schliebar ist.
* Schliebar heit, es hat einen Closer.
*)
VAR wdwPtr : ptrWdwSlot;
BEGIN
wdwPtr := FindWindow (wdw);
IF wdwPtr # NIL
THEN
RETURN (MagicAES.CLOSER IN wdwPtr^.comps);
END;
RETURN IsInQueue (wdw);
END WindowIsCloseable;
PROCEDURE WindowIsFullable (wdw: INTEGER) : BOOLEAN;
(* Liefert TRUE, wenn das Window vorhanden und fullbar ist,
* d.h. es hat einen Sizer oder es ist nur in der Queue drin.
*)
VAR wdwPtr : ptrWdwSlot;
BEGIN
wdwPtr := FindWindow (theTopWindow);
IF wdwPtr # NIL
THEN
RETURN (MagicAES.Size IN wdwPtr^.comps) &
(MagicAES.FULL IN wdwPtr^.comps);
END;
RETURN IsInQueue (wdw);
END WindowIsFullable;
PROCEDURE ClickInWindow (x, y: INTEGER; VAR wdw: INTEGER);
(* Liefert das Windowhandle zurck, falls sich an der Position
* x,y ein Fenster befindet (mu nicht dem Modul bekannt sein!)
*)
BEGIN
wdw := MagicAES.WindFind (x, y);
END ClickInWindow;
(*------- Menu & Keyboard -----------------------------------------------------*)
PROCEDURE InstallGlobalMenu (tree: ADDRESS; menuP: handleMessProc);
(* Gibt dem Modul die Adresse des Menubaums bekannt. Damit kann dieser dann disablet
* werden, wenn ein modaler Dialog aufgerufen wird.
* Auerdem wird eine Callback-Funktion installiert, die bei Menu-Events aufgerufen
* wird.
* Es wird nur ein Menu und eine Callbackfunktion verwendet, ein Deinstall
* ist daher nicht notwendig, ein erneuter Aufruf berschreibt die
* eingestellten Werte
*)
BEGIN
globalMenu := tree;
handleGlobalMess := menuP;
END InstallGlobalMenu;
PROCEDURE DisableMenu (menu: ADDRESS; disable : BOOLEAN);
(* Schaltet einen Menubaum auf enabled oder disabled
* menu = NIL: ein installiertes globales Menu wird disabled oder enabled
*)
VAR o, title : INTEGER;
t : mtUtils.tObjcTree;
n : ADDRESS;
BEGIN
IF menu = NIL
THEN
menu := globalMenu;
END;
IF menu = NIL
THEN
RETURN
END;
IF disable
THEN
INC (disableCounter);
ELSE
DEC (disableCounter);
END;
IF disable & (disableCounter > 1) THEN RETURN END;
IF ~disable & (disableCounter > 0) THEN RETURN END;
IF menuDisabled = disable THEN RETURN END;
t:= menu;
title:= t^[t^[t^[0].obHead].obHead].obHead; (* Index erster Titel *)
o := MagicAES.MenuBar(menu, MagicAES.Reset);
o:= t^[t^[t^[0].obHead].obNext].obHead; (* Index erste Box *)
mtUtils.SetState(t, t^[o].obHead, MagicAES.DISABLED, disable); (* ersten Eintrag *)
LOOP (* 1 *)
IF title > t^[title].obNext THEN EXIT; (* LOOP 1 *) END;
title:= t^[title].obNext;
mtUtils.SetState(t, title, MagicAES.DISABLED, disable); (* titel disablen *)
mtUtils.ExclState(t, title, MagicAES.SELECTED); (* deselektieren *)
END; (* LOOP 1 *)
IF disable
THEN
menuLength := t^[2].obWidth;
t^[2].obWidth:= t^[3].obWidth; (* Breite auf DESK begrenzen *)
ELSE
t^[2].obWidth:= menuLength; (* Breite zurcksetzen *)
END;
o := MagicAES.MenuBar(menu, MagicAES.Set);
menuDisabled := disable;
END DisableMenu;
PROCEDURE InstallGlobalKeyProc (key : handleGlobalKeyProc);
(* Installiert einen globalen Keyhandler, der dann aufgerufen wird, wenn
* die Taste von keinem Fenster behandelt wurde.
* Wenn Shift und eine andere Sondertaste gedrckt wird, dann wird
* diese Callback-Funktion vor den Fenstern aufgerufen
*)
BEGIN
handleGlobalKey := key;
END InstallGlobalKeyProc;
(*------- QueueModul ----------------------------------------------------------*)
CONST maxQueueEntries = 255;
TYPE queueEntry = RECORD
wdw : INTEGER;
apId : INTEGER;
END;
VAR handleArray : ARRAY[0..maxQueueEntries] OF queueEntry;
maxQueue : CARDINAL;
PROCEDURE InitQueue();
VAR z : CARDINAL;
BEGIN
FOR z := 0 TO maxQueueEntries DO handleArray[z].wdw := -999 END;
maxQueue := 0;
END InitQueue;
PROCEDURE GetApId (wdw : INTEGER; VAR apId : INTEGER) : BOOLEAN;
VAR z : INTEGER;
info : ARRAY [0..3] OF INTEGER;
BEGIN
(* Application ID rausfinden *)
IF ((multiTOS OR (magIx & (magIxVer > $200)))
& (wdw > 0))
THEN
MagicAES.WindGet (wdw, MagicAES.WFOWNER, info);
IF MagicAES.CallResult # 0 THEN
apId := info[0];
RETURN TRUE;
END;
END;
FOR z := 0 TO INTEGER(maxQueue)-1 DO
IF handleArray[z].wdw = wdw
THEN
apId := handleArray[z].apId;
RETURN TRUE
END;
END;
RETURN FALSE;
END GetApId;
PROCEDURE EnQueue(wdw, apId : INTEGER; reverse : BOOLEAN);
VAR z : INTEGER;
BEGIN
IF reverse
THEN
INC(maxQueue);
FOR z := INTEGER(maxQueue)-2 TO 0 BY -1 DO
handleArray[z+1] := handleArray[z];
END;
handleArray[0].wdw := wdw;
handleArray[0].apId:= apId;
ELSE
handleArray[maxQueue].wdw := wdw;
handleArray[maxQueue].apId:= apId;
INC(maxQueue);
END;
END EnQueue;
PROCEDURE DeleteFromQueue(item : INTEGER);
VAR z : CARDINAL;
newState : BITSET;
BEGIN
z := 0;
WHILE (z < maxQueue) & (handleArray[z].wdw # item) DO INC(z) END;
IF (z < maxQueue) & (handleArray[z].wdw = item) THEN
FOR z := z TO maxQueue DO handleArray[z] := handleArray[z+1] END;
handleArray[maxQueue].wdw := -999;
DEC(maxQueue);
END;
END DeleteFromQueue;
PROCEDURE TopOfQueue(VAR item, apId : INTEGER);
BEGIN
item := handleArray[0].wdw;
apId := handleArray[0].apId;
END TopOfQueue;
PROCEDURE FindSpecialTop (proc: queueTestProc): INTEGER;
VAR i: INTEGER;
BEGIN
FOR i := INTEGER(maxQueue) -1 TO 0 BY -1 DO
IF (handleArray[i].apId = mtAppl.ApplIdent)
& proc (handleArray[i].wdw)
THEN
RETURN handleArray[i].wdw;
END;
END;
RETURN -1;
END FindSpecialTop;
PROCEDURE BottomOfQueue(VAR item, apId : INTEGER);
BEGIN
IF maxQueue >= 1
THEN
item := handleArray[maxQueue-1].wdw;
apId := handleArray[maxQueue-1].apId;
ELSE
item := handleArray[0].wdw;
apId := handleArray[0].apId;
END;
END BottomOfQueue;
PROCEDURE EmptyQueue():BOOLEAN;
BEGIN
RETURN maxQueue = 0
END EmptyQueue;
PROCEDURE NewWindowIsTop(handle, apId : INTEGER);
BEGIN
DeleteFromQueue(handle);
EnQueue(handle, apId, FALSE);
IF handleNewTop # handleNewTopProc (NIL)
THEN
handleNewTop (handle);
END;
END NewWindowIsTop;
PROCEDURE BringToBottom(handle, apId : INTEGER);
BEGIN
DeleteFromQueue(handle);
EnQueue(handle, apId, TRUE);
END BringToBottom;
PROCEDURE WindowIsClosed(handle : INTEGER);
BEGIN
DeleteFromQueue(handle)
END WindowIsClosed;
PROCEDURE SendRedraw (win: INTEGER; r : Rectangle);
TYPE messArray = RECORD
mid,
apid,
over,
wdw : INTEGER;
area : Rectangle;
END;
VAR mess : messArray;
apId : INTEGER;
BEGIN
v.bool := GetApId (win, apId);
mess := messArray{MagicAES.WMREDRAW, mtAppl.ApplIdent, 0, win, r};
MagicAES.ApplWrite(apId, 16, mess);
END SendRedraw;
PROCEDURE SendMess (win, apId, msg : INTEGER);
TYPE msgArray = RECORD
mid,
apid,
over,
wdw : INTEGER;
r1,
r2 : LONGINT;
END;
VAR mess : msgArray;
BEGIN
mess := msgArray{msg, mtAppl.ApplIdent, 0, win, 0, 0};
MagicAES.ApplWrite(apId, 16, mess);
END SendMess;
PROCEDURE SendTop(win, apId : INTEGER);
BEGIN
SendMess (win, apId, MagicAES.WMTOPPED);
END SendTop;
PROCEDURE SendClosed(win, apId : INTEGER);
BEGIN
SendMess (win, apId, MagicAES.WMCLOSED);
END SendClosed;
PROCEDURE SendFulled (win, apId : INTEGER);
BEGIN
SendMess (win, apId, MagicAES.WMFULLED);
END SendFulled;
PROCEDURE TopNextWindow();
VAR nextTop, apId : INTEGER;
wdwPtr : ptrWdwSlot;
BEGIN
IF ~EmptyQueue() THEN
TopOfQueue(nextTop, apId);
IF (nextTop # -999) THEN
IF nextTop >= 0 THEN
wdwPtr := FindWindow (nextTop);
IF wdwPtr # NIL
THEN
topWdw (wdwPtr, TRUE);
ELSE
SendTop(nextTop, apId);
NewWindowIsTop(nextTop, apId);
END
END;
END;
END;
END TopNextWindow;
PROCEDURE TopLastWindow();
VAR nextTop, apId : INTEGER;
wdwPtr : ptrWdwSlot;
BEGIN
IF ~EmptyQueue() THEN
BottomOfQueue(nextTop, apId);
IF (nextTop # -999) THEN
IF nextTop >= 0 THEN
wdwPtr := FindWindow (nextTop);
IF wdwPtr # NIL
THEN
topWdw (wdwPtr, TRUE);
ELSE
SendTop(nextTop, apId);
NewWindowIsTop(nextTop, apId);
END
END;
END;
END;
END TopLastWindow;
PROCEDURE GetOwnTopWindow (VAR wdw: INTEGER);
VAR i : INTEGER;
wdwPtr : ptrWdwSlot;
BEGIN
IF ~EmptyQueue() THEN
FOR i := maxQueue-1 TO 0 BY -1 DO
wdw := handleArray[i].wdw;
IF wdw >= 0
THEN
wdwPtr := FindWindow (wdw);
IF wdwPtr # NIL
THEN
RETURN
END;
END;
END;
END;
wdw := -1;
END GetOwnTopWindow;
PROCEDURE TopNextPossible() : BOOLEAN;
BEGIN
RETURN maxQueue >= 1
END TopNextPossible;
PROCEDURE IsInQueue (wdw : INTEGER) : BOOLEAN;
(* Liefert TRUE zurck, wenn das Fenster wdw in
* der verwalteten Queue ist.
*)
BEGIN
RETURN GetApId (wdw, v.int);
END IsInQueue;
PROCEDURE GetSecondWdw (VAR wdw : INTEGER): BOOLEAN;
(* Liefert zweitoberstes Fenster zurck.
* Geht nur ber Queue, benutzt nicht die Liste.
*)
BEGIN
IF maxQueue <= 1 THEN RETURN FALSE; END;
wdw := handleArray[maxQueue-2].wdw;
RETURN TRUE;
END GetSecondWdw;
PROCEDURE ArrangeWindows (mode : INTEGER);
(* Ordnet die Fenster
*)
VAR wdwPtr : ptrWdwSlot;
i,
wdws : INTEGER;
newSize : Rectangle;
cols, rows,
xcols, xrows : INTEGER;
BEGIN
wdws := 0;
(* Fenster zhlen *)
wdwPtr := windows;
WHILE wdwPtr # NIL DO
IF (MagicAES.Size IN wdwPtr^.comps) &
~wdwPtr^.isIcon &
~wdwPtr^.isHidden
THEN INC (wdws); END;
wdwPtr := wdwPtr^.next;
END;
IF wdws <= 1 THEN RETURN END;
i := 1;
wdwPtr := windows;
(* Letzten Eintrag suchen *)
WHILE wdwPtr^.next # NIL DO
wdwPtr := wdwPtr^.next
END;
CASE mode OF
STACKED : WHILE (i <= wdws) & (wdwPtr # NIL) DO
IF (MagicAES.Size IN wdwPtr^.comps)
& ~wdwPtr^.isIcon & ~wdwPtr^.isHidden
THEN
WITH newSize DO
x := deskSize.x; (* new.x *)
y := deskSize.y + (i-1) * (deskSize.h DIV wdws); (* new.y *)
w := deskSize.w; (* new.w *)
h := deskSize.h DIV wdws; (* new.h *)
END;
moveSizeWdw (wdwPtr, TRUE, FALSE, newSize, TRUE);
INC (i);
END;
wdwPtr := wdwPtr^.prev;
END; |
BYSIDE : WHILE (i <= wdws) & (wdwPtr # NIL) DO
IF (MagicAES.Size IN wdwPtr^.comps)
& ~wdwPtr^.isIcon & ~wdwPtr^.isHidden
THEN
WITH newSize DO
x := deskSize.x + (i-1) * (deskSize.w DIV wdws); (* new.x *)
y := deskSize.y; (* new.y *)
w := deskSize.w DIV wdws; (* new.w *)
h := deskSize.h; (* new.h *)
END;
moveSizeWdw (wdwPtr, TRUE, FALSE, newSize, TRUE);
INC (i);
END;
wdwPtr := wdwPtr^.prev;
END; |
OVERLAP : WHILE (i <= wdws) & (wdwPtr # NIL) DO
IF (MagicAES.Size IN wdwPtr^.comps)
& ~wdwPtr^.isIcon & ~wdwPtr^.isHidden
THEN
WITH newSize DO
x := deskSize.x + (i-1) * mtAppl.CharHeight; (* new.x *)
y := deskSize.y + (i-1) * mtAppl.CharHeight; (* new.y *)
w := deskSize.w - (wdws-1) * mtAppl.CharHeight; (* new.w *)
h := deskSize.h - (wdws-1) * mtAppl.CharHeight; (* new.h *)
END;
moveSizeWdw (wdwPtr, TRUE, FALSE, newSize, TRUE);
INC (i);
END;
wdwPtr := wdwPtr^.prev;
END; |
TILED : (* Erstmal rausfinden, wieviel Fenster nebeneinander kommen *)
cols := 2;
WHILE cols*cols < wdws DO INC (cols) END;
rows := wdws DIV cols;
IF rows * cols < wdws THEN xrows := rows+1 ELSE xrows := rows END;
xcols := wdws - (rows * cols);
IF xcols = 0 THEN xcols := cols END;
WHILE ( (i-1) DIV cols < rows) & (wdwPtr # NIL) DO
IF (MagicAES.Size IN wdwPtr^.comps)
& ~wdwPtr^.isIcon & ~wdwPtr^.isHidden
THEN
WITH newSize DO
x := deskSize.x + ((i-1) MOD cols) * (deskSize.w DIV cols); (* new.x *)
y := deskSize.y + ((i-1) DIV cols) * (deskSize.h DIV xrows); (* new.y *)
w := deskSize.w DIV cols; (* new.w *)
h := deskSize.h DIV xrows; (* new.h *)
END;
moveSizeWdw (wdwPtr, TRUE, FALSE, newSize, TRUE);
INC (i);
END;
wdwPtr := wdwPtr^.prev;
END;
WHILE ( i <= wdws) & (wdwPtr # NIL) DO
IF (MagicAES.Size IN wdwPtr^.comps)
& ~wdwPtr^.isIcon & ~wdwPtr^.isHidden
THEN
WITH newSize DO
x := deskSize.x + ((i-1) MOD xcols) * (deskSize.w DIV xcols); (* new.x *)
y := deskSize.y + ((i-1) DIV cols) * (deskSize.h DIV xrows); (* new.y *)
w := deskSize.w DIV xcols; (* new.w *)
h := deskSize.h DIV xrows; (* new.h *)
END;
moveSizeWdw (wdwPtr, TRUE, FALSE, newSize, TRUE);
INC (i);
END;
wdwPtr := wdwPtr^.prev;
END;
|
ELSE
END;
END ArrangeWindows;
(*-- Drag & Drop Support fr MTOS ------------------------------------------*)
PROCEDURE WdwInstallDDClient (wdw: INTEGER;
getExts : getExtsProc;
acceptData : acceptDataProc;
writeData : writeDataProc);
(* Ein Fenster installiert fr sich Drag & Drop. Damit untersttzt
* es automatisch Drag & Drop.
*)
VAR wdwPtr : ptrWdwSlot;
BEGIN
wdwPtr := FindWindow (wdw);
IF wdwPtr # NIL
THEN
WITH wdwPtr^ DO
ddClientInstalled := TRUE;
ddGetExts := getExts;
ddAcceptData := acceptData;
ddWriteData := writeData;
END;
END;
END WdwInstallDDClient;
PROCEDURE WdwInstallDDServer (wdw: INTEGER;
getHeader : getHeaderProc;
readData : readDataProc);
(* Ein Fenster installiert sich als Server fr Drag & Drop.
* Danach kann es dann die Prozedur WdwDDServe benutzen,
* die Drag & Drop durchfhrt.
*)
VAR wdwPtr : ptrWdwSlot;
BEGIN
wdwPtr := FindWindow (wdw);
IF wdwPtr # NIL
THEN
WITH wdwPtr^ DO
ddServerInstalled := TRUE;
ddGetHeader := getHeader;
ddReadData := readData;
END;
END;
END WdwInstallDDServer;
PROCEDURE WdwDoesDragDrop (wdw: INTEGER): BOOLEAN;
(* TRUE: Das Fenster untersttzt Drag & Drop
*)
VAR wdwPtr : ptrWdwSlot;
BEGIN
wdwPtr := FindWindow (wdw);
IF wdwPtr # NIL
THEN
RETURN wdwPtr^.ddClientInstalled
END
END WdwDoesDragDrop;
PROCEDURE WdwDDGetExts (wdw: INTEGER; VAR exts: ARRAY OF CHAR);
(* Liefert fr das Wdw die untersttzen Extensions zurck
*)
VAR wdwPtr : ptrWdwSlot;
BEGIN
wdwPtr := FindWindow (wdw);
IF wdwPtr # NIL
THEN
IF wdwPtr^.ddClientInstalled
THEN
wdwPtr^.ddGetExts (wdw, wdwPtr^.special, exts);
END;
END;
END WdwDDGetExts;
PROCEDURE WdwDDAcceptData (wdw: INTEGER; hdr: ADDRESS): BOOLEAN;
(* Falls das Window die Daten nach dem Header akzeptiert, dann wird
* TRUE zurckgegeben
*)
VAR wdwPtr : ptrWdwSlot;
BEGIN
wdwPtr := FindWindow (wdw);
IF wdwPtr # NIL
THEN
IF wdwPtr^.ddClientInstalled
THEN
RETURN wdwPtr^.ddAcceptData (wdw, wdwPtr^.special, hdr);
END;
END;
RETURN FALSE
END WdwDDAcceptData;
PROCEDURE WdwDDWriteData (wdw: INTEGER; VAR data: ADDRESS; dataLen: LONGCARD);
(* Die Daten werden an das Fenster bergeben
*)
VAR wdwPtr : ptrWdwSlot;
BEGIN
wdwPtr := FindWindow (wdw);
IF wdwPtr # NIL
THEN
IF wdwPtr^.ddClientInstalled
THEN
wdwPtr^.ddWriteData (wdw, wdwPtr^.special, data, dataLen);
END;
END;
END WdwDDWriteData;
(*
* create a pipe for doing the drag & drop,
* and send an AES message to the receipient
* application telling it about the drag & drop
* operation.
*
* Input Parameters:
* apid: AES id of the window owner
* winid: target window (0 for background)
* msx, msy: mouse X and Y position
* (or -1, -1 if a fake drag & drop)
* kstate: shift key state at time of event
*
* Output Parameters:
* exts: A 32 byte buffer into which the
* receipient's 8 favorite
* extensions will be copied.
*
* Returns:
* A positive file descriptor (of the opened
* drag & drop pipe) on success.
* -1 if the receipient doesn't respond or
* returns DD_NAK
* -2 if appl_write fails
*)
PROCEDURE WdwDDCreate (apId, wdw, mx, my : INTEGER; kstate: BITSET;
VAR exts: ARRAY OF CHAR; VAR oldPipe: ADDRESS): INTEGER;
TYPE msgArray = RECORD
mid,
apid,
over,
win,
x,
y : INTEGER;
kbd : BITSET;
ch1,
ch2 : CHAR;
END;
VAR fd, i : INTEGER;
msg : msgArray;
fdMask : MagicSys.lBITSET;
c : CHAR;
pipename: ARRAY [0..255] OF CHAR;
count : LONGCARD;
BEGIN
(* create pipe *)
Strings.Assign ('U:\PIPE\DRAGDROP.AA', pipename, v.bool);
fd := -1;
LOOP
INC (pipename[18]);
IF pipename[18] > 'Z'
THEN
INC (pipename[17]);
IF pipename[17] > 'Z' THEN
EXIT
END;
END;
(* HIDDEN means "get EOF if nobody has pipe open for reading" *)
fd := MagicDOS.Fcreate (pipename, {MagicDOS.Hidden});
IF fd # MagicDOS.EAccDn THEN EXIT END;
END;
(* test file handle *)
IF fd < 0
THEN
(* Fcreate error *)
RETURN fd
END;
(* set SIG_PIPE to SIG_IGN *)
oldPipe := Mintbind.Psignal (Mintbind.SIGPIPE, Mintbind.SIG_IGN);
(* construct and send the AES message *)
msg := msgArray{MagicAES.AP_DRAGDROP, mtAppl.ApplIdent, 0, wdw, mx, my,
kstate,pipename[17],pipename[18]};
MagicAES.ApplWrite(apId, 16, msg);
(* now wait for a response *)
fdMask := MagicSys.lBITSET{fd};
v.lcard := 0;
i := Mintbind.Fselect ( (*MagicAES.DD_TIMEOUT*) 1000, fdMask, v.lbset, 0);
IF (i=0) OR (fdMask = MagicSys.lBITSET{})
THEN
(* timeout happened *)
v.a := Mintbind.Psignal (Mintbind.SIGPIPE, oldPipe);
v.int := MagicDOS.Fclose (fd);
RETURN -1;
END;
(* read the 1 byte response *)
count := 1;
MagicDOS.Fread (fd, count, ADR(c));
IF (count # 1) OR (ORD(c) # MagicAES.DD_OK)
THEN
(* no drag & drop *)
v.a := Mintbind.Psignal (Mintbind.SIGPIPE, oldPipe);
v.int := MagicDOS.Fclose (fd);
RETURN -1;
END;
(* now read the "preferred extensions" *)
count := MagicAES.DD_EXTSIZE;
MagicDOS.Fread(fd, count, ADR(exts));
IF count # MagicAES.DD_EXTSIZE
THEN
(* Read error in pipe *)
v.a := Mintbind.Psignal (Mintbind.SIGPIPE, oldPipe);
v.int := MagicDOS.Fclose (fd);
RETURN -1
END;
(* init was ok *)
RETURN fd
END WdwDDCreate;
(*
* see if the receipient is willing to accept a certain
* type of data (as indicated by "ext")
*
* Input parameters:
* fd file descriptor returned from ddcreate()
* ext pointer to the 4 byte file type
* name pointer to the name of the data
* size number of bytes of data that will be sent
*
* Output parameters: none
*
* Returns:
* DD_OK if the receiver will accept the data
* DD_EXT if the receiver doesn't like the data type
* DD_LEN if the receiver doesn't like the data size
* DD_NAK if the receiver aborts
*)
PROCEDURE WdwDDstry (fd: INTEGER; REF ext, name: ARRAY OF CHAR; size: LONGCARD): INTEGER;
VAR hdrLen, i : INTEGER;
fdMask : MagicSys.lBITSET;
c : CHAR;
count : LONGCARD;
BEGIN
(*$W-*)
(* 4 bytes for extension, 4 bytes for size, 1 byte for
* trailing 0
*)
hdrLen := 9 + LENGTH(name);
count := 2;
MagicDOS.Fwrite(fd, count, ADR(hdrLen));
IF count # 2 THEN RETURN MagicAES.DD_NAK END;
(* now send the header *)
count := 4;
MagicDOS.Fwrite (fd, count, ADR(ext));
i := SHORT(count);
count := 4;
MagicDOS.Fwrite (fd, count, ADR(size));
INC (i, count);
count := LENGTH (name) + 1;
MagicDOS.Fwrite (fd, count, ADR(name));
INC (i, count);
IF i # hdrLen THEN RETURN MagicAES.DD_NAK END;
(* now wait for a response *)
fdMask := MagicSys.lBITSET{fd};
v.lcard := 0;
(* wait to a maximum of 100 ms *)
i := Mintbind.Fselect (100, fdMask, v.lbset, 0);
IF (i=0) OR (fdMask = MagicSys.lBITSET{})
THEN
(* timeout happened *)
RETURN MagicAES.DD_NAK;
END;
(* wait for a reply *)
count := 1;
MagicDOS.Fread(fd, count, ADR(c));
IF (i # 1) THEN RETURN MagicAES.DD_NAK; END;
RETURN ORD(c);
(*$W=*)
END WdwDDstry;
(*
* close a drag & drop operation
*)
PROCEDURE WdwDDclose (fd: INTEGER; oldPipe: ADDRESS);
BEGIN
(* restore signal handler *)
v.a := Mintbind.Psignal (Mintbind.SIGPIPE, oldPipe);
(* close pipe *)
v.int := MagicDOS.Fclose (fd);
END WdwDDclose;
PROCEDURE WdwInternalDD (server, client: ptrWdwSlot);
VAR hdr : POINTER TO RECORD
dtype : ARRAY [0..3] OF CHAR;
dlen : LONGCARD;
dname : ARRAY [0..2047] OF CHAR;
END;
ext : ARRAY [0..3] OF CHAR;
name : ARRAY [0..79] OF CHAR;
size : LONGCARD;
data : ADDRESS;
done : BOOLEAN;
BEGIN
WITH server^ DO
IF ddGetHeader (wdw, special, HDRFIRST, ext, name, size)
THEN
done := FALSE;
REPEAT
(* Header aufbauen *)
ALLOCATE (hdr, 9 + LENGTH (name));
IF hdr = NIL THEN RETURN END;
hdr^.dtype := ext;
hdr^.dlen := size;
Strings.Assign (name, hdr^.dname, v.bool);
(* Beim Client anfragen, ob er den Header annimmt *)
IF client^.ddAcceptData (client^.wdw, client^.special, hdr)
THEN
(* Daten holen *)
ddReadData (wdw, special, data);
IF data # NIL
THEN
client^.ddWriteData (client^.wdw, client^.special, data, size);
DEALLOCATE (data, 0);
done := TRUE;
END;
END;
DEALLOCATE (hdr, 0);
UNTIL done OR ~ddGetHeader (wdw, special, HDRNEXT, ext, name, size);
END;
END;
END WdwInternalDD;
PROCEDURE WdwDDServe (wdw: INTEGER; mx, my: INTEGER; kstate: BITSET): BOOLEAN;
(* Initialisiert Drag & Drop als Server. wdw ist das Source-Fenster(!!),
* vorher mu sich das Fenster als Server angemeldet haben. Dann wird
* ber die angemeldeten Prozeduren versucht, Drag & Drop durchzufhren
*)
VAR wdwPtr,
wdwPtr2 : ptrWdwSlot;
exts : ARRAY [0..MagicAES.DD_EXTSIZE-1] OF CHAR;
ext : ARRAY [0..7] OF CHAR;
name : ARRAY [0..79] OF CHAR;
tWin : INTEGER;
info : ARRAY [0..3] OF INTEGER;
res,
fd : INTEGER;
size : LONGCARD;
oldPipe : ADDRESS;
data : ADDRESS;
fdMask : MagicSys.lBITSET;
BEGIN
wdwPtr := FindWindow (wdw);
IF wdwPtr # NIL
THEN
IF wdwPtr^.ddServerInstalled
THEN
(* Ok, wir haben einen Server
* Jetzt das Zielfenster finden
*)
tWin := MagicAES.WindFind (mx, my);
(* Drag & Drop im gleichen Fenster geht nicht *)
IF tWin = wdw THEN RETURN FALSE END;
wdwPtr2 := FindWindow (tWin);
IF wdwPtr2 # NIL
THEN
(* Ist eigenes Fenster! Eventuell internes Drag & Drop durchfhren
*)
IF wdwPtr2^.ddClientInstalled
THEN
(* Do internal drag & drop *)
WdwInternalDD (wdwPtr, wdwPtr2);
END;
(* Hier knnen wir rausgehen, da passiert nichts mehr *)
RETURN TRUE
END;
(* Ok, ist fremdes Fenster *)
(* Wenn kein multiTasking OS, dann abbrechen *)
IF ~(multiTOS OR (magIx & (magIxVer > $200))) THEN RETURN FALSE END;
(* Application ID rausfinden *)
MagicAES.WindGet (tWin, MagicAES.WFOWNER, info);
IF MagicAES.CallResult = 0 THEN RETURN FALSE END; (* keine Application gefunden *)
IF info[0] = mtAppl.ApplIdent THEN RETURN FALSE END; (* this should NOT happen! *)
(* create drag & drop pipe *)
fd := WdwDDCreate (info[0], tWin, mx, my, kstate, exts, oldPipe);
IF fd < 0 THEN
RETURN FALSE
END;
(* Die gelieferten Extensions ignorieren wir einfach *)
(* Beim Server die ersten Headerdaten anfordern *)
IF wdwPtr^.ddGetHeader (wdwPtr^.wdw, wdwPtr^.special, HDRFIRST, ext, name, size)
THEN
REPEAT
(* Header senden und nachsehen, ob es akzeptiert wird *)
res := WdwDDstry (fd, ext, name, size);
IF res = MagicAES.DD_OK
THEN
(* Daten holen *)
wdwPtr^.ddReadData (wdwPtr^.wdw, wdwPtr^.special, data);
IF data # NIL
THEN
(* Daten schreiben in pipe *)
MagicDOS.Fwrite (fd, size, data);
(* Speicher freigeben *)
DEALLOCATE (data, 0);
(* now wait for a response *)
fdMask := MagicSys.lBITSET{fd};
v.lcard := 0;
(* wait a little bit before closing the pipe *)
v.int := Mintbind.Fselect (100, fdMask, v.lbset, 0);
ELSE
(* Fehler beim holen der Daten, abbrechen *)
res := MagicAES.DD_NAK;
END;
ELSE
IF (res # MagicAES.DD_NAK)
& ~wdwPtr^.ddGetHeader (wdwPtr^.wdw, wdwPtr^.special, HDRNEXT, ext, name, size)
THEN
(* DD_EXT or DD_LEN, aber kein weiterer Header, also abbrechen *)
res := MagicAES.DD_NAK;
END;
END;
UNTIL (res = MagicAES.DD_OK) OR (res = MagicAES.DD_NAK);
END;
(* Pipe wieder schlieen *)
WdwDDclose(fd, oldPipe);
RETURN TRUE;
END;
END;
RETURN FALSE;
END WdwDDServe;
PROCEDURE windowTerm();
VAR wdwPtr,
dummyPtr : ptrWdwSlot;
voidO : BOOLEAN;
BEGIN
wdwPtr := windows;
WHILE wdwPtr # NIL DO
WITH wdwPtr^ DO
voidO := hdlClose(wdw, vdi, special, TRUE);
(* Fenster noch schlieen *)
MagicAES.WindClose (wdw);
MagicAES.WindDelete (wdw);
WindowIsClosed (wdw);
(* Workstation schlieen *)
IF vdi > 0 THEN
mtAppl.CloseWorkstation (vdi);
END;
END;
dummyPtr := wdwPtr;
wdwPtr := wdwPtr^.next;
DISPOSE (dummyPtr);
END;
END windowTerm;
PROCEDURE EnableIconify (enable: BOOLEAN);
BEGIN
iconifySupportEnabled := enable;
END EnableIconify;
PROCEDURE SetMagicPCKeyTranslation (setIt: BOOLEAN);
(* Schaltet die Tastenbersetzung fr MagicPC ein *)
BEGIN
MagicPCKeyTrans := setIt;
END SetMagicPCKeyTranslation;
CONST
(* Cookies definieren *)
MagiXCookie = 'MagX';
MultiGEMCookie = 'MGEM';
TYPE magAESVARS = RECORD
magic : LONGCARD; (* mu $87654321 sein *)
membot : ADDRESS; (* Ende der AES- Variablen *)
aes_start : ADDRESS; (* Startadresse *)
magic2 : LONGCARD; (* ist 'MAGX' *)
date : LONGCARD; (* Erstelldatum *)
chgres : ADDRESS; (* void ( *chgres)(int res, int txt); /* Auflsung ndern *)
shel_vector: ADDRESS; (* long ( **shel_vector)(void); /* residentes Desktop *)
aes_bootdrv: ADDRESS; (* char *aes_bootdrv; /* von hieraus wurde gebootet *)
vdi_device : ADDRESS; (* int *vdi_device; /* vom AES benutzter Treiber *)
(* zustzliche Variablen, die nicht dokumentiert sind *)
nvdi_work : ADDRESS; (* void **nvdi_workstation; /* vom AES benutzte Workstation *)
shelw_doex : ADDRESS; (* int *shelw_doex; /* shel-write variable *)
shelw_isgr : ADDRESS; (* int *shelw_isgr; /* shel-write variable *)
version : INTEGER; (* int version; /* in Hex 0111 (BCD) *)
release : INTEGER; (* int release; /* +224 = Zeichen der Version *)
_basepage : LONGCARD;
moff_cnt : ADDRESS; (* int *moff_cnt; *)
shel_buf_len: LONGCARD; (* long shel_buf_len; *)
shel_buf : ADDRESS; (* long shel_buf; *)
ntrdy_list : LONGCARD; (* long notready_list; *)
menu_up : LONGCARD; (* long menu_up; *)
menutree : LONGCARD; (* long menutree; *)
desktree : LONGCARD; (* long desktree; *)
desk_1stob : LONGCARD; (* long desktree_1stob; *)
dos_magic : LONGCARD; (* long dos_magic; *)
max_windn : LONGCARD; (* long maxwindn; *)
fsel : ADDRESS; (* int ( **fsel) (char* path, char* name, int* button, char* title); *)
dummy : LONGCARD; (* long dummy; *)
END;
AESVARPTR = POINTER TO magAESVARS;
magXCookiePtr = POINTER TO RECORD
config_status : LONGCARD; (* long config_status; *)
dosvars : ADDRESS; (* DOSVARS *dosvars; *)
aesvars : AESVARPTR; (* AESVARS *aesvars; *)
END;
VAR magX_ptr : magXCookiePtr;
BEGIN
iconifySupportEnabled := FALSE;
InitQueue(); (* Init Window Queue *)
(* Init der anderen Variablen *)
MagicAES.WindGet (0, MagicAES.WFWORKXYWH, deskSize); (* Gre des Desktops abfragen *)
windows := NIL;
control7:= ADR (VDIControl[7]);
control9:= ADR (VDIControl[9]);
(* Term-Proc anmelden *)
mtAppl.InstallTermproc (windowTerm);
(* globale Prozeduren initialisieren *)
handleNewTop := handleNewTopProc(NIL); (* Siehe Kommentar zu Typ *)
handlePostEvent := handleEventProc(NIL); (* Siehe Kommentar zu Typ *)
handleGlobalKey := handleGlobalKeyProc (NIL);
handleGlobalMess := handleMessProc (NIL);
multiTOS := MagicAES.AESGlobal.apVersion >= $400;
(* Cookie abfragen, ob Mag!X *)
magIx := ~multiTOS &
MagicCookie.FindCookie (MagiXCookie, magX_ptr);
IF magIx
THEN
magIxVer := magX_ptr^.aesvars^.version;
END;
MagicAES.hasAgi := MagicAES.hasAgi OR
(magIx & (magIxVer >= $200));
onlyOneTop := -1;
iconHdl := NIL;
allIconified := FALSE;
globalMenu := NIL;
disableCounter := 0;
menuDisabled := FALSE;
MagicPCKeyTrans := FALSE;
END WdwManager.